本來之前以為,not exists 和之前的參數一樣的也是需要分情況來說,但是做了實驗測試之後發現。Not exists 和not in 的選擇方法十分的簡單,就是只選 not exists 因為 not in加上了不會走索引。而not exists 會走。這樣就限定了,如果要使用的話就儘可能使用n ...
本來之前以為,not exists 和之前的參數一樣的也是需要分情況來說,但是做了實驗測試之後發現。Not exists 和not in 的選擇方法十分的簡單,就是只選 not exists 因為 not in加上了不會走索引。而not exists 會走。這樣就限定了,如果要使用的話就儘可能使用not exists。
Not exists 的意思是,關聯查詢,返回除了關聯子查詢所得結果之外的值,
看如下的執行計劃和代價便可以看出來。兩者的差距。
SCOTT@ rac1>select * from emp where empno not in (select empno from t4 where t4.deptno=20) ;
9 rows selected.
Elapsed: 00:00:01.72
Execution Plan
----------------------------------------------------------
Plan hash value: 3504968978
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 20 | 1120 | 6130 (2)| 00:00:01 |
|* 1 | HASH JOIN ANTI NA | | 20 | 1120 | 6130 (2)| 00:00:01 |
| 2 | TABLE ACCESS FULL| EMP | 20 | 600 | 3 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| T4 | 1354K| 33M| 6120 (2)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("EMPNO"="EMPNO")
3 - filter("T4"."DEPTNO"=20)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
1 db block gets
43236 consistent gets
21573 physical reads
0 redo size
1391 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
9 rows processed
SCOTT@ rac1>select * from emp where not exists (select empno from t4 where emp.deptno=t4.deptno and t4.deptno=20) ;
9 rows selected.
Elapsed: 00:00:05.45
Execution Plan
----------------------------------------------------------
Plan hash value: 3745834269
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 20 | 860 | 2033 (98)| 00:00:01 |
| 1 | NESTED LOOPS ANTI | | 20 | 860 | 2033 (98)| 00:00:01 |
| 2 | TABLE ACCESS FULL| EMP | 20 | 600 | 3 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | DEPTNOIND | 1 | 13 | 101 (99)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("T4"."DEPTNO"=20)
filter("EMP"."DEPTNO"="T4"."DEPTNO")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
7754 consistent gets
7724 physical reads
0 redo size
1374 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
9 rows processed
最後來寫個總結,之前到現在一共寫了三篇關於 exists 的文章,自覺有點繁瑣。但也是自己不斷學習的過程。很多東西還是需要自己不斷的去操作,思考。總結。言歸正傳。
exists 和 in 在兩張表差不多大小的情況下,效率,速度,是不會相差很大的。
在一大一小的情況下是存在效率上的差別的。儘管他們的執行計劃有可能是相同的。 exists 更適用於 子表大,in 適用於父表大。具體請看第二篇。
not exsits 與not in 相比,not in 之前已經看過了,並不會走相關的索引。所以,儘量使用 not exists。
另,這兩個查詢中如果有null值,會返回全部的結果集。所以註意寫語句的時候儘量避開null值。
在這裡祝大家,新年快樂吧,給自己定一個小目標。只要是工作日,每天堅持寫一篇博客。努力學習,爭取早日變成一個自己所期待的樣子!加油2018.