動態SQL.綁定變量.靜態SQL的性能對比

1 測試樣例

下面的三個存儲過程,分別使用了動態SQL、綁定變量、靜態SQL三種編程方式。具體存儲過程內容如下:

l 動態SQL

create or replace procedure proc1 as

begin

for i in 1 .. 100000 loop

execute immediate 'insertinto t values (' || i || ')';

commit;

end loop;

end proc1;

l 綁定變量

create or replace procedure proc2 as

begin

for i in 1 .. 100000 loop execute immediate 'insert into t values(:X)' using i; commit;

end loop;

end proc2;

l 靜態SQL

create or replace procedure proc3 as

begin

for i in 1 .. 100000 loop

insert into t values(i); commit;

end loop;

end proc3;

2 測試過程

測試過程的步驟爲

1) drop table t purge;

2) create table t (x int);

3) alter system flush shared_pool;

4) set timing on

5) exec procxxx;

6) select count(*) from t;

在上述的測試過程中,由於每次測試時的表全是新的,並刷新了共享池,所以每次的測試效果還是比較正確的。此次測試是在物理機上進行的測試,而非虛擬機上進行測試。

3 測試結果3.1 動態SQL

Proc1存儲過程使用了動態SQL,這樣就會在每次執行insert語句時,要對每一個insert語句進行硬解析,這樣就增加了共享池的硬解析開銷,下面是v$sql視圖中的結果

SQL_TEXT EXECUTIONS PARSE_CALLS

------------------------------------------------------------ -----------

BEGINproc1; END; 1 1

insertinto t values (99280) 1 1

insertinto t values (99310) 1 1

insertinto t values (99362) 1 1

insertinto t values (99377) 1 1

insertinto t values (99399) 1 1

insertinto t values (99474) 1 1

insertinto t values (99544) 1 1

insertinto t values (99592) 1 1

insertinto t values (99601) 1 1

insertinto t values (99634) 1 1

insertinto t values (99696) 1 1

insertinto t values (99746) 1 1

insertinto t values (99804) 1 1

insertinto t values (99807) 1 1

insertinto t values (99859) 1 1

insertinto t values (99861) 1 1

insertinto t values (99930) 1 1

insertinto t values (99936) 1 1

insertinto t values (99956) 1 1

proc1存儲過程,在本次測試中使用了24.25秒,具體結果如下

SQL> exec proc1;

PL/SQL procedure successfully completed.

Elapsed: 00:00:24.25

3.2 綁定變量

Proc2存儲過程使用了綁定變量,這樣在執行過程上,就會減少硬解析的開銷,降低共享池的爭用。在執行過程中,v$sql視圖中的結果如下

SQL_TEXT EXECUTIONS PARSE_CALLS

------------------------------------------------------------ -----------

BEGIN proc2;END; 1 1

insert intot values (:X) 100000 0

insert語句並沒有解析1次執行1次,而是解析了1次,執行了10萬次。Proc2存儲過程,在本次測試中使用了20.94秒,執行結果如下

SQL>exec proc2;

PL/SQL proceduresuccessfully completed.

Elapsed:00:00:20.94

3.3 靜態SQL

Proc3存儲過程使用了靜態SQL,這樣在編譯過程中insert語句就解析好了,而不像proc2存儲過程需要在執行過程中再解析,這樣節省了一些時間,具體的測試結果如下

SQL_TEXT EXECUTIONS PARSE_CALLS

------------------------------------------------------------ -----------

BEGINproc3; END; 1 1

INSERTINTO T VALUES(:B1 ) 100000 0

在靜態SQL中,insert語句也是使用了綁定變量,所以也是解析1次,然後多次執行。Proc3存儲過程執行了17.82秒,具體結果如下

SQL>exec proc3;

PL/SQL proceduresuccessfully completed.

Elapsed:00:00:17.82

4 測試總結

動態SQL適用於表名及查詢字段名未知的情況。在已知查詢字段名及表名的情況下,使用動態SQL(字符串拼接方式)會增加硬解析的開銷,在這種情況下,建議使用靜態SQL,這樣可以提高執行效率。在過程過程用拼湊的動態sql效率並不高,有時候還不如程序直接傳遞sql.靜態SQL是前置編譯綁定,動態SQL是後期執行時才編譯綁定

參考:

< Oracle專家高級編程>



轉載自:動態SQL.綁定變量.靜態SQL的性能對比

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章