在作業中遇到一個SQL查詢中IN的引數會打到11萬的數量,所以就想提高一下運行效率就寫了另外一種EXISTS寫法的SQL執行結果令我十分意外,
關于ORACLE對于IN的引數限制
Oracle 9i 中個數不能超過256,Oracle 10g個數不能超過1000.但是在Oracle 11g中已經解除了這個限制
我用的是Oracle 11g
執行SQL
SQL A :
IN寫法
select DISTINCT
a.aay002 as CODENAME,
a.aay003 as CODEVALUE
from A a left join P p on a.aay002 = p.aay002
where 1=1
and a.bya343 is not null and a.bya343 <> 0
and a.aae100 = '1'
and a.aay103 = '2AA'
and a.aab038 in (
select unit_code from
(select code UNIT_CODE, name COMENAME from B
where 1=1
and unit_level in ('2','3','4','5')
and is_enabled = '1'
start with id= '00000000' connect by prior id = parent_id
)
)
order by a.aay002
查詢結果:212條資料,耗時:2.773秒
SQL B :
EXISTS寫法
select DISTINCT
a.aay002 as CODENAME,
a.aay003 as CODEVALUE
from A a left join P p on a.aay002 = p.aay002
where
exists
(select 1 from B
where code = a.aab038
start with id = '00000000'
connect by prior id = parent_id)
and a.bya343 is not null and a.bya343 <> 0
and a.aae100 = '1'
and a.aay103 = '2AA'
order by a.aay002;
A表資料量:9040條
B表資料量:111839條
P表資料量:50條
查詢結果:212條資料,耗時:137.548秒
個人總結:在Oracle 11g以后查詢SQL中IN效率比EXISTS快很多
但是在網上查詢到的資訊是:
舉例:
select * from A where id in(select id from B);
select * from A where exists (select 1 from B where A.id = B.id);
如:A表有10000條記錄,B表有1000000條記錄,那么exists()會執行10000次去判斷A表中的id是否與B表中的id相等,
如:A表有10000條記錄,B表有100000000條記錄,那么exists()還是執行10000次,因為它只執行A.length次,可見B表資料越多,越適合exists()發揮效果,
再如:A表有10000條記錄,B表有100條記錄,那么exists()還是執行10000次,還不如使用in()遍歷10000*100次,因為in()是在記憶體里遍歷比較,而exists()需要查詢資料庫,我們都知道查詢資料庫所消耗的性能更高,而記憶體比較很快
結論:exists()適合B表比A表資料大的情況
當A表資料與B表資料一樣大時,in與exists效率差不多,可任選一個使用,
與網上結論相駁,原因目前懷疑可能與表結構與索引有關,如有新的進展會繼續更新,目前還是用IN效率高
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/262446.html
標籤:其他
上一篇:資料型別
下一篇:2021-02-22
