資料庫為啥要使用引數繫結?

2021-09-01 09:59:19 字數 2520 閱讀 7592

儲存過程(stored procedure)是在大型資料庫系統中,一組為了完成特定功能的sql 語句集,經編譯後儲存在資料庫中,使用者通過指定儲存過程的名字並給出引數(如果該儲存過程帶有引數)來執行它。

1. 為什麼使用繫結變數?

這是解決oracle應用程式可伸縮性的乙個關鍵環節;而oracle的共享池就決定了開發人員必須使用繫結變數;如果想要oracle 執行減慢,甚至完全終止,那就可以不用繫結變數;

這裡舉例說明上述問題;

為了查詢乙個員工代號是123,你可以這樣查詢:

select * from emp where empno=』123』;

你也可以這樣查詢:

select * from emp where empno=:empno;

象我們往常一樣,你查詢員工』123』一次以後,有可能再也不用;接著你有可能查詢員工』456』,然後查詢』789』等等;如果查詢使用象第乙個查詢語句,你每次查詢都是乙個新的查詢(我們叫它硬編碼的查詢方法);因此,oracle每次必須分析,解析,安全檢查, 優化等等;

第二個查詢語句提供了繫結變數:empno,它的值在查詢執行時提供,查詢經過一次編譯後,查詢方案儲存在共享池中,可以用來檢索和重用;在效能和伸縮性方面,這兩者的差異是巨大的,甚至是驚人的;通俗點講,就不是乙個級別;

第乙個查詢使用的頻率越高,所消耗的系統硬體資源越大,從而降低了使用者的使用數量;它也會把優化好的其它查詢語句從共享池中踢出;就象乙個老鼠壞了一鍋湯似的,系統的整體效能降低; 而執行繫結變數,提交相同物件的完全相同的查詢的使用者(這句話,大家聽起來比較難理解,隨後我會給出詳細的解釋),一次性使用就可重複使用,其效率不言耳語; 打個形象的比喻來說,第乙個查詢就象一次性使用的筷子,而第二個查詢象是鐵筷子,只要洗乾淨,張三李四都能用,合理有效地使用了資源;

2、關於oracle資料庫的引數繫結效能實踐的乙個例項簡介。

ad:

從oracle的sga的構成來看,它是推崇使用引數繫結的。使用引數繫結可以有效的使用share pool,對已經快取的sql不用再硬解析,能明顯的提高效能。

具體實踐如下:

sql>create table test (a number(10));<

再建立乙個儲存過程:

create or replace procedure p_test is

i number(10);

begin

i := 0;

while i <= 100000 loop

execute immediate ' insert into test values (' || to_char(i) || ')';

i := i + 1;

end loop;

commit;

end p_test;

先測試沒有使用引數繫結的:

執行 p_test 後,用時91.111秒。

再建立乙個使用引數繫結的:

create or replace procedure p_test is

i number(10);

begin

i := 0;

while i <= 100000 loop

execute immediate ' insert into test values (:a)'

using i;

i := i + 1;

end loop;

commit;

end p_test;

執行 p_test 後,用時55.099秒。

從上面的執行時間可以看出,兩者性相差 39.525%,可見,用不用引數繫結在效能上相差是比較大的。

3、那麼使用語句引數的方式,和使用字串處理函式的方式相比,有什麼好處呢?主要有以下三點:

(1) 使用「語句引數」方式,具有更高的安全性,可以有效防止「sql注入攻擊」。 「sql注入攻擊」要想達到目的,就必須讓attack value隨著sql命令字串一起傳送進sql解析器。黑客如果在一條sql命令字串被送入到sqlite3_prepare函式之前,利用c字串處理函式等途徑將attack value注入其中,而在sqlite3_prepare函式之中進行解析(parse),就可以達到攻擊目的。而使用「語句引數」方式,被傳送到sqlite3_prepare函式的只是sql命令字串中的引數符號(如:「?」),而不是具體的值。在sqlite3_prepare函式執行之後,才會使用bind函式給引數符號繫結具體的值,這就可以避免attack value隨著sql命令字串一起在sqlite3_prepare函式中被解析,從而有效躲避「sql注入攻擊」。

(2)使用「語句引數」方式,可以更快的完成值替換。

(3)使用「語句引數」方式,更節省記憶體。原因是使用如snprintf函式,需要乙個sql命令模板,一塊足夠大的輸出快取,而且字串處理函式需要工作記憶體(working memory),除此之外對於整形,浮點型,特別是blobs,經常會占用更多的空間。

為什麼要使用NoSQL資料庫

工作中遇到的挑戰 1,高併發讀寫 web2.0 資料庫併發負載非常高,往往達到每秒上萬次的讀寫請求 2,高容量儲存和高效儲存 web2.0 通常需要在後台資料庫中儲存海量資料,如何儲存海量資料並進行高效的查詢往往是乙個挑戰 3,高擴充套件性和高可用性 隨著系統的使用者量和訪問量與日俱增,需要資料庫能...

為什麼要使用NoSQL資料庫

工作中遇到的挑戰 1,高併發讀寫 web2.0 資料庫併發負載非常高,往往達到每秒上萬次的讀寫請求 2,高容量儲存和高效儲存 web2.0 通常需要在後台資料庫中儲存海量資料,如何儲存海量資料並進行高效的查詢往往是乙個挑戰 3,高擴充套件性和高可用性 隨著系統的使用者量和訪問量與日俱增,需要資料庫能...

yii2 0 資料庫操作 引數繫結

當使用帶引數的 sql 來建立資料庫命令時,你幾乎總是應該使用繫結引數的方法來防止 sql 注入攻擊,例如 bindvalue id get id bindvalue status 1 queryone 繫結引數的方法 params id get id status 1 bindvalues par...