In和exists使用及效能分析(一):in的使用
本節主要討論in的原理及使用,以及常見的錯誤的觀點。
一、in的使用
1.1 in的使用
1.1.1 內、外兩表關聯欄位都非空
SQL> select * from tb1;
T1 NAME1
---------- ----------
1 1
2 2
SQL> select * from tb2;
T2 NAME2
---------- ----------
2 2
SQL> select count(1) from tb1 where t1 in (select t2 from tb2);
--T1=2的記錄符合條件,結果符合常規思維
COUNT(1)
----------
1
SQL> select count(1) from tb1 where t1 not in (select t2 from tb2);
--T1=1的記錄符合條件,結果符合常規思維
COUNT(1)
----------
1
1.1.2 當外表關聯欄位無空值、內表關聯列表有空值時
SQL> select * from tb1;
T1 NAME1
---------- ----------
1 1
2 2
SQL> select * from tb2;
T2 NAME2
---------- ----------
2 2
3
SQL> select count(1) from tb1 where t1 in (select t2 from tb2);
--T1=2的記錄符合條件,結果符合常規思維
COUNT(1)
----------
1
SQL> select count(1) from tb1 where t1 not in (select t2 from tb2);
--無記錄符合條件,結果不符合常規思維
COUNT(1)
----------
0
SQL> select count(1) from tb1 where t1 in (select t2 from tb2 where t2 is not null);
--T1=2的記錄符合條件,結果符合常規思維
COUNT(1)
----------
1
SQL> select count(1) from tb1 where t1 not in (select t2 from tb2 where t2 is not null);
--T1=2的記錄符合條件,結果符合常規思維
COUNT(1)
----------
1
1.1.3當外表關聯欄位有空值、內表關聯列表無空值時
SQL> select * from tb1;
T1 NAME1
---------- ----------
1 1
1
2 2
SQL> select * from tb2;
T2 NAME2
---------- ----------
2 2
3 3
SQL> select count(1) from tb1 where t1 in (select t2 from tb2);
--T1=2的記錄符合查詢條件,符合常規思維
COUNT(1)
----------
1
SQL> select count(1) from tb1 where t1 not in (select t2 from tb2);
--只有T1=2的記錄符合查詢條件,與常規思維相悖
COUNT(1)
----------
1
1.1.4 當內、外表的關聯欄位都有空值時
SQL> select * from tb1;
T1 NAME1
---------- ----------
1 1
2 2
3
SQL> select * from tb2;
T2 NAME2
---------- ----------
2 2
3
SQL> select count(1) from tb1 where t1 in (select t2 from tb2);
--只有t1=2的記錄符合條件,與常規思維相悖
COUNT(1)
----------
1
SQL> select count(1) from tb1 where t1 not in (select t2 from tb2);
--沒有符合條件的記錄,與常規思維相悖
COUNT(1)
----------
0
SQL> select count(1) from tb1 where t1 in (select t2 from tb2 where t2 is not null);
--只有t1=2的記錄符合條件,符合常規思維
COUNT(1)
----------
1
SQL> select count(1) from tb1 where t1 not in (select t2 from tb2 where t2 is not null);
--只有t1=1的記錄符合條件,與常規思維相悖
COUNT(1)
----------
1
1.1.5 外表無記錄
SQL> select * from tb1;
T1 NAME1
---------- ----------
SQL> select * from tb2;
T2 NAME2
---------- ----------
2 2
3 3
SQL> select count(1) from tb1 where t1 in (select t2 from tb2);
--無記錄返回
COUNT(1)
----------
0
SQL> select count(1) from tb1 where t1 not in (select t2 from tb2);
--無記錄返回
COUNT(1)
----------
0
這裡很容易理解,無論條件成立與否,因為外表無記錄,索引返回記錄數為0
1.1.6 內表無記錄
SQL> select * from tb1;
T1 NAME1
---------- ----------
1 1
2 2
SQL> select * from tb2;
T2 NAME2
---------- ----------
SQL> select count(1) from tb1 where t1 in (select t2 from tb2);
--所有記錄都不符合條件,結果符合常規思維
COUNT(1)
----------
0
SQL> select count(1) from tb1 where t1 not in (select t2 from tb2);
--所有記錄都符合條件,結果符合常規思維
COUNT(1)
----------
2
1.2 in運算總結:
1.2.1單列作in運算時
1. col in (v1,v2,...vn) 相當於 (col=v1 or col=v2 or ...col=vn)
col not in (v1,v2,...vn) 相當於 (col<>v1 and col<>v2 and ...col<>vn)
2. 當in 列表的記錄數大於0,且in列表(vn)有null值時,則oracle在處理 in 的時候轉換成:
(col=v1 or col=v2 or col=null or ...col=vn)
所以,in列表有null值不會引起與常規思維不一樣的結果
3. 當not in 列表的記錄數大於0,且not in列表有null值時,oracle在處理not in 當時候轉換成:
(col<>v1 and col<>v2 and col<>null and ...col<>vn),由於oracle中null是一個非常特殊的值,null與任何值做算術運算子比較都返回false,由於多個條件是用and連線的,所以這種情況整個條件是false,也就不會有記錄返回。
這種情況是最容易搞混和不理解的。
4. 當in/not in 列表的記錄數大於0,且col是null值時,null與任何值做算術運算子比較都返回false,根據in和not in的處理方式可知,無論是in運算還是not in 運算,oracle不會有任何記錄返回。也就是說oracle在處理時相當於把col是null的記錄忽略不作處理。
5. 當in/not in 列表的記錄數為0時(注意與in/not in列表全為空不同),in運算相當於條件1=2;not in運算相當於1=1;
6. 在not in操作中,可以在子查詢中加入col is not null使得有記錄返回
1.2.2 多列作in運算時
1. (col1,col2) in ((v11,v12),(v21,v22),...(vn1,vn2))相當於
((col1=v11 and col2=v12) or (col1=v21 and col2=v21) ... or (col1=vn1 and col2=vn2))
(col1,col2) not in ((v11,v12),(v21,v22),...(vn1,vn2))相當於
((col1<>v11 or col2<>v12) and (col1<>v21 or col2<>v22) and ...(col1<>vn1 or col2<>vn2))
2. 多列in運算當原理和單列一樣,把col1和col2看作一個整體col,把vn1和vn2看作一個整體vn就相當於單列作in運算了。
3. 多列運算比較特殊當兩種情況是col1和col2都為null時,相當於單列中都col為null,oracle在處理這種情況時,相當於忽略這條記錄;
當vn1和vn2都為null時,相當於單列運算中vn為null的情況,在作in運算時不會影響返回結果,但在作not in運算時不會有任何記錄返回。
4. 當col1和col2中有一個為null時,作in運算時oracle相當於把該記錄忽略不計,因為(null or null or null...)結果是null。(not in不能忽略)
5. 當col1和col2其中一個為null,且另一個的值在包含在not in列表中時,在作not in運算時oracle相當於把該記錄忽略不計(null && true/false結果是null)。
6. 在not in操作中,可以在子查詢加入((col1 is not null) or (col2 is not null))使得有結果返回
7. 以上小結適用於in/not in 列表的記錄數大於0的情況
8. any、all運算與in類似
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/231499/viewspace-63763/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- In和exists使用及效能分析(三):in和exists的效能分析
- In和exists使用及效能分析(二):exists的使用
- sql中in和exists的原理及使用場景。SQL
- [精選] SQL中的IN與NOT IN、EXISTS與NOT EXISTS的區別及效能分析SQL
- 對線面試官:SQL中的IN與NOT IN、EXISTS與NOT EXISTS的區別及效能分析面試SQL
- perf及火焰圖的使用,效能分析
- Oralce 使用SQL中的exists 和not exists 用法詳解SQL
- exists和not exists及in和not in的用法與區別
- MySQL下Limit使用及效能分析MySqlMIT
- Oracle 中不使用NOT IN 和 NOT EXISTS的另一種方法Oracle
- SQL中EXISTS的使用SQL
- Unity效能分析(一)流程與工具的使用Unity
- Oracle中exists和in的效能差異Oracle
- C#中使用反射的使用實現和效能分析(轉)C#反射
- 使用Android Profile做效能分析及優化Android優化
- mysql 關於exists 和in分析MySql
- 使用xhprof進行線上PHP效能追蹤及分析PHP
- mongodb之使用explain和hint效能分析和優化MongoDBAI優化
- golang 使用pprof和go-torch做效能分析Golang
- [Oracle] exists 和 not existsOracle
- in,exists和not exists ,not in與null的一些關係記載Null
- Oracle學習系列—資料庫優化—In和Exists的使用Oracle資料庫優化
- MySQL-09.效能分析工具的使用MySql
- 使用表連線替代exists
- 使用pprof進行效能分析
- perf效能分析工具使用分享
- oracle中的exists和not exists和in用法詳解Oracle
- in和exists的一些區別
- 7 個使用 bcc/BPF 的效能分析神器
- 使用VisualVM對JAVA程式進行效能分析及調優LVMJava
- oracle中的exists 和not exists 用法詳解Oracle
- SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差別SQL
- oracle中關於in和exists,not in 和 not existsOracle
- ThreadPoolExecutor的使用及原始碼分析thread原始碼
- STL的map使用和分析
- Laravel Event的分析和使用Laravel
- in/exists和not in/not exists執行效率
- SDWebImage使用及原始碼分析Web原始碼