綁定變量
在查詢(xún)中,綁定變量是一個(gè)占位符。例如,為了檢索員工123的記錄,可以查詢(xún):
select * from scott.emp where empno = 123;
另外,也可以查詢(xún):
select * from scott.emp where empno = :empno;
在典型系統(tǒng)中,查詢(xún)員工123一次,可能再也不會(huì)查詢(xún)。以后,將查詢(xún)員工456,然后查詢(xún)員工789等等。
如果在查詢(xún)中使用文字(常量),那每次每個(gè)查詢(xún)都是一個(gè)新查詢(xún),即在數(shù)據(jù)庫(kù)中以前沒(méi)有過(guò)的查詢(xún)。每次查詢(xún)必需經(jīng)過(guò)分析、限定(名稱(chēng)解析)、
安全檢查、優(yōu)化等等,簡(jiǎn)單的說(shuō),執(zhí)行的每條語(yǔ)句在每次執(zhí)行時(shí)都將必需經(jīng)過(guò)編譯。
第二個(gè)查詢(xún)使用了綁定變量:empno,它的值在查詢(xún)執(zhí)行時(shí)提供。查詢(xún)經(jīng)過(guò)一次編譯后,考試大提示查詢(xún)方案存儲(chǔ)在共享池(庫(kù)高速緩存)中,可以用來(lái)檢索和重用。
在性能的差異是巨大的。
---
如果使用綁定變量,提交引用相同對(duì)象的完全相同的查詢(xún)的人將使用共享池中的編譯方案。只需編譯子例程一次,就可以重復(fù)使用。
不僅使用較少的資源,而且可以減少鎖存時(shí)間,降低鎖存頻率。這會(huì)他提高性能,并大大地提高可伸縮性。
--測(cè)試(根據(jù)機(jī)器不同而不同哦,本測(cè)試同一機(jī)器)
--使用了綁定變量的
declare
type rc is ref cursor;
l_rc rc;
l_dummy all_objects.object_name%type;
l_start number default sys.dbms_utility.get_time;
begin
for i in 1..1000 loop
open l_rc for
'select a.object_name from all_objects a where a.object_id = :X' using i;
fetch l_rc into l_dummy;
close l_rc;
end loop;
dbms_output.put_line(round((sys.dbms_utility.get_time - l_start)/100,2)||'秒');
end;
-------------------------------
--結(jié)果輸出為0.91秒
-------------------------------
--沒(méi)有綁定
declare
type rc is ref cursor;
l_rc rc;
l_dummy all_objects.object_name%type;
l_start number default sys.dbms_utility.get_time;
begin
for i in 1..1000 loop
open l_rc for
'select a.object_name from all_objects a where a.object_id = ' ||i;
fetch l_rc into l_dummy;
close l_rc;
end loop;
dbms_output.put_line(round((sys.dbms_utility.get_time - l_start)/100,2)||'秒');
end;
-------------------------------
--結(jié)果輸出為22.42秒
-------------------------------
查詢(xún)通常只是因?yàn)楦淖僿here子句中的內(nèi)容而產(chǎn)生不同的結(jié)果。為了在這種情況下避免硬解析,需要使用綁定變量(bind variable)。它是用戶(hù)放入查詢(xún)中的占位符,它會(huì)告訴Oracle"我會(huì)隨后為這個(gè)變量提供一個(gè)值,現(xiàn)在需要生成一個(gè)方案,但我實(shí)際執(zhí)行語(yǔ)句的時(shí)候,我會(huì)為您提供應(yīng)該使用的實(shí)際值"。
select * from emp where ename='KING'; //不使用綁定變量
select * from emp where ename=:bv //使用綁定變量
一般在 procedure or function 中使用,可以?xún)?yōu)化共享池的使用。
例子:
SQL> set serveroutput on
SQL> drop table hxz_12 ;
表已丟棄。
SQL> create table hxz_12(c number);
表已創(chuàng)建。
SQL> --考試大提示未綁定變量
SQL> declare
2 l_start number default dbms_utility.get_time;
3 l_tabname varchar2(10) default 'hxz_12';
4 begin
5 for x in 1 .. 10000 loop
6 Execute immediate 'insert into '||l_tabname||'(c) values (' || x || ')';
7 end loop;
8 dbms_output.put_line(round((dbms_utility.get_time - l_start) / 100, 2) ||
9 ' seconds...');
10 commit;
11 end;
12 /
2.89 seconds...
PL/SQL 過(guò)程已成功完成。
SQL> declare
2 l_start number default dbms_utility.get_time;
3 l_tabname varchar2(10) default 'hxz_12';
4 begin
5 for x in 1 .. 10000 loop
6 Execute immediate 'insert into '||l_tabname||'(c) values (:v)'
7 using x;
8 end loop;
9 dbms_output.put_line(round((dbms_utility.get_time - l_start) / 100, 2) ||
10 ' seconds...');
11 commit;
12 end;
13 /
.74 seconds...
PL/SQL 過(guò)程已成功完成。
SQL>
Examda提示可見(jiàn)進(jìn)行了變量綁定執(zhí)行起來(lái)效果比沒(méi)有進(jìn)行變量綁定的要好很多。
在查詢(xún)中,綁定變量是一個(gè)占位符。例如,為了檢索員工123的記錄,可以查詢(xún):
select * from scott.emp where empno = 123;
另外,也可以查詢(xún):
select * from scott.emp where empno = :empno;
在典型系統(tǒng)中,查詢(xún)員工123一次,可能再也不會(huì)查詢(xún)。以后,將查詢(xún)員工456,然后查詢(xún)員工789等等。
如果在查詢(xún)中使用文字(常量),那每次每個(gè)查詢(xún)都是一個(gè)新查詢(xún),即在數(shù)據(jù)庫(kù)中以前沒(méi)有過(guò)的查詢(xún)。每次查詢(xún)必需經(jīng)過(guò)分析、限定(名稱(chēng)解析)、
安全檢查、優(yōu)化等等,簡(jiǎn)單的說(shuō),執(zhí)行的每條語(yǔ)句在每次執(zhí)行時(shí)都將必需經(jīng)過(guò)編譯。
第二個(gè)查詢(xún)使用了綁定變量:empno,它的值在查詢(xún)執(zhí)行時(shí)提供。查詢(xún)經(jīng)過(guò)一次編譯后,考試大提示查詢(xún)方案存儲(chǔ)在共享池(庫(kù)高速緩存)中,可以用來(lái)檢索和重用。
在性能的差異是巨大的。
---
如果使用綁定變量,提交引用相同對(duì)象的完全相同的查詢(xún)的人將使用共享池中的編譯方案。只需編譯子例程一次,就可以重復(fù)使用。
不僅使用較少的資源,而且可以減少鎖存時(shí)間,降低鎖存頻率。這會(huì)他提高性能,并大大地提高可伸縮性。
--測(cè)試(根據(jù)機(jī)器不同而不同哦,本測(cè)試同一機(jī)器)
--使用了綁定變量的
declare
type rc is ref cursor;
l_rc rc;
l_dummy all_objects.object_name%type;
l_start number default sys.dbms_utility.get_time;
begin
for i in 1..1000 loop
open l_rc for
'select a.object_name from all_objects a where a.object_id = :X' using i;
fetch l_rc into l_dummy;
close l_rc;
end loop;
dbms_output.put_line(round((sys.dbms_utility.get_time - l_start)/100,2)||'秒');
end;
-------------------------------
--結(jié)果輸出為0.91秒
-------------------------------
--沒(méi)有綁定
declare
type rc is ref cursor;
l_rc rc;
l_dummy all_objects.object_name%type;
l_start number default sys.dbms_utility.get_time;
begin
for i in 1..1000 loop
open l_rc for
'select a.object_name from all_objects a where a.object_id = ' ||i;
fetch l_rc into l_dummy;
close l_rc;
end loop;
dbms_output.put_line(round((sys.dbms_utility.get_time - l_start)/100,2)||'秒');
end;
-------------------------------
--結(jié)果輸出為22.42秒
-------------------------------
查詢(xún)通常只是因?yàn)楦淖僿here子句中的內(nèi)容而產(chǎn)生不同的結(jié)果。為了在這種情況下避免硬解析,需要使用綁定變量(bind variable)。它是用戶(hù)放入查詢(xún)中的占位符,它會(huì)告訴Oracle"我會(huì)隨后為這個(gè)變量提供一個(gè)值,現(xiàn)在需要生成一個(gè)方案,但我實(shí)際執(zhí)行語(yǔ)句的時(shí)候,我會(huì)為您提供應(yīng)該使用的實(shí)際值"。
select * from emp where ename='KING'; //不使用綁定變量
select * from emp where ename=:bv //使用綁定變量
一般在 procedure or function 中使用,可以?xún)?yōu)化共享池的使用。
例子:
SQL> set serveroutput on
SQL> drop table hxz_12 ;
表已丟棄。
SQL> create table hxz_12(c number);
表已創(chuàng)建。
SQL> --考試大提示未綁定變量
SQL> declare
2 l_start number default dbms_utility.get_time;
3 l_tabname varchar2(10) default 'hxz_12';
4 begin
5 for x in 1 .. 10000 loop
6 Execute immediate 'insert into '||l_tabname||'(c) values (' || x || ')';
7 end loop;
8 dbms_output.put_line(round((dbms_utility.get_time - l_start) / 100, 2) ||
9 ' seconds...');
10 commit;
11 end;
12 /
2.89 seconds...
PL/SQL 過(guò)程已成功完成。
SQL> declare
2 l_start number default dbms_utility.get_time;
3 l_tabname varchar2(10) default 'hxz_12';
4 begin
5 for x in 1 .. 10000 loop
6 Execute immediate 'insert into '||l_tabname||'(c) values (:v)'
7 using x;
8 end loop;
9 dbms_output.put_line(round((dbms_utility.get_time - l_start) / 100, 2) ||
10 ' seconds...');
11 commit;
12 end;
13 /
.74 seconds...
PL/SQL 過(guò)程已成功完成。
SQL>
Examda提示可見(jiàn)進(jìn)行了變量綁定執(zhí)行起來(lái)效果比沒(méi)有進(jìn)行變量綁定的要好很多。

