oracle如何查询系统变量数据,Oracle如何对IN子查询使用绑定变量(转)
當前位置:我的異常網? 數據庫???Oracle如何對IN子查詢使用綁定變量(轉)
Oracle如何對IN子查詢使用綁定變量(轉)
www.myexceptions.net??網友分享于:2013-08-01??瀏覽:65次
Oracle怎么對IN子查詢使用綁定變量(轉)
在實際使用中,經常會有帶in的子查詢,如where id in (1,2,3)這樣的情況,但是如果很多這樣的語句在數據庫中出現,將引起數據庫的大量硬解析與共享池SQL碎片。所以,在實際應用中,可以采用其他方法,將這些in list給綁定起來。
如果需要綁定in list,首先,需要創建兩個類型(type):
針對數據類型的
CREATE OR REPLACE TYPE NUMTABLETYPE as table of number;
針對字符串類型的(每個list的單元大小不要超過1000字節)
create or replace type vartabletype as table of varchar2(1000);
然后創建兩個相關的函數
數字列表函數
create or replace function str2numList( p_string in varchar2 ) return numTableType
as
v_str long default p_string || ‘,‘;
v_n number;
v_data numTableType := numTableType();
begin
loop
v_n := to_number(instr( v_str, ‘,‘ ));
exit when (nvl(v_n,0) = 0);
v_data.extend;
v_data( v_data.count ) := ltrim(rtrim(substr(v_str,1,v_n-1)));
v_str := substr( v_str, v_n+1 );
end loop;
return v_data;
end;
字符列表函數
create or replace function str2varList( p_string in varchar2 ) return VarTableType
as
v_str long default p_string || ‘,‘;
v_n varchar2(2000);
v_data VarTableType := VarTableType();
begin
loop
v_n :=instr( v_str, ‘,‘ );
exit when (nvl(v_n,0) = 0);
v_data.extend;
v_data( v_data.count ) := ltrim(rtrim(substr(v_str,1,v_n-1)));
v_str := substr( v_str, v_n+1 );
end loop;
return v_data;
end;
創建之后,我們就可以采用如下的方式來使用in list的綁定了。如可以采用如下的三種方案
SELECT /*+ ordered use_nl(a,u) */ id, user_id, BITAND(promoted_type,4) busauth
from table(STR2NUMLIST(:bind0)) a,
bmw_users u
where u.user_id = a.column_value;
SELECT? /*+ leading(a) */ id, user_id, BITAND(promoted_type,4) busauth
from bmw_users u where user_id in
(select * from table(STR2NUMLIST(:bind0)) a);
SELECT? /*+ index(bmw_users UK_BMW_USERS_USERID) */ id, user_id
from bmw_users where user_id in
(SELECT * FROM THE (SELECT CAST(STR2NUMLIST(:bind0) AS NUMTABLETYPE)
FROM dual) WHERE rownum<1000); 在如上的方案中,以上語句中的hint提示,是為了穩定執行計劃,防止Oracle對in list的錯誤估計而導致走hash連接。一般建議采用第一種方法,比較簡單可靠并且可以指定穩定的計劃。但是要求數據庫的版本比較高,在老版本中(8i),可能只能采用第三種方法。總的來說,1、2兩種方法比3要少6個邏輯讀左右。如:SQL> SELECT /*+ ordered use_nl(a,u) */ id, user_id
2?? from table(STR2NUMLIST(’1,2,3′)) a,
3?? bmw_users u
4*? where u.user_id = a.column_value
Execution Plan
———————————————————-
0????? SELECT STATEMENT Optimizer=CHOOSE (Cost=3279 Card=8168 Bytes =334888)
1??? 0?? NESTED LOOPS (Cost=3279 Card=8168 Bytes=334888)
2??? 1???? COLLECTION ITERATOR (PICKLER FETCH) OF ‘STR2NUMLIST’
3??? 1???? TABLE ACCESS (BY INDEX ROWID) OF ‘BMW_USERS’ (Cost=1 Card=1 Bytes=39)
4??? 3?????? INDEX (UNIQUE SCAN) OF ‘UK_BMW_USERS_USERID’ (UNIQUE)
Statistics
———————————————————-
0? recursive calls
0? db block gets
10? consistent gets
0? physical reads
0? redo size
……
SQL> SELECT? /*+ index(bmw_users UK_BMW_USERS_USERID) */ id, user_id
2?? from bmw_users where user_id in
3*? (SELECT * FROM THE (SELECT CAST(STR2NUMLIST(’1,2,3′) AS NUMTABLETYPE) FROM dual) WHERE rownum<1000)
Execution Plan
———————————————————-
0????? SELECT STATEMENT Optimizer=CHOOSE (Cost=430 Card=999 Bytes=51948)
1??? 0?? NESTED LOOPS (Cost=430 Card=999 Bytes=51948)
2??? 1???? VIEW OF ‘VW_NSO_1′ (Cost=11 Card=999 Bytes=12987)
3??? 2?????? SORT (UNIQUE)
4??? 3???????? COUNT (STOPKEY)
5??? 4?????????? COLLECTION ITERATOR (PICKLER FETCH) OF ‘STR2NUMLIST’
6??? 5???????????? TABLE ACCESS (FULL) OF ‘DUAL’ (Cost=2 Card=82)
7??? 1???? TABLE ACCESS (BY INDEX ROWID) OF ‘BMW_USERS’ (Cost=1 Card=1 Bytes=39)
8??? 7?????? INDEX (UNIQUE SCAN) OF ‘UK_BMW_USERS_USERID’ (UNIQUE)
Statistics
———————————————————-
0? recursive calls
0? db block gets
16? consistent gets
0? physical reads
0? redo size
文章評論
總結
以上是生活随笔為你收集整理的oracle如何查询系统变量数据,Oracle如何对IN子查询使用绑定变量(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 整个表空间迁移,ORACL
- 下一篇: Oracle数据库迁移后变慢,迁移数据之