16 反連線 anti join 優化主題系列

2021-08-09 04:52:42 字數 2297 閱讀 1159

反連線

(anti-join)

反連線其實是特殊的半連線。只是把

in/exists

換成了notin/not exists

執行計畫中,看到有

nested loops anti/hash join anti

就表示有反連線

舉個例子(基於

hroracle11gr2

)下面有2個

sql:

select department_name

from hr.departments dept

where department_id not in

(select department_id from hr.employees emp);

select department_name

from hr.departments dept

where not exists (select null from hr.employees emp

where emp.department_id = dept.department_id);

以上兩個

sql不等價

執行計畫是

filter

對吧??

就是正常的

join

方式了吧

令人驚訝的是,

not in

不返回結果,

notexists

返回16行。

這裡也說明

not in

和notexists

不能像in

和exists

那樣隨意改寫

sql。

為什麼用

not in

不返回結果呢??因為子查詢

select department_id from hr.employees emp

會返回null

值。oracle

有個缺陷: in

裡面有null

值會返回結果,比如下面

sql

select department_name from hr.departments dept wheredepartment_id in(10,50,null); 單

not in

裡面有null

值就不會返回結果,直接返回

null

select department_name from hr.departments dept wheredepartment_id not in(10,50,null);

我們在做

sql優化的時候,一定要注意

not in

和notexists

是不是能等價轉換。

當然了,一般情況下,

notin

子查詢裡面都會排除有

null

的情況,不然查詢結果沒意義。

現在來過濾掉

null值。

是不是說a有

並且b沒有b

用null代替

那我加個

where

條件is null

b.*** is null

是不是說明a和

b 沒關聯上??

是不是等效於

notin,not exists

的效果

總結一下

in/exists

,notin/not exists

一般情況下,當

sql很簡單,他們的執行計畫是一樣的,也就是說他們的效能時一樣的。但是

sql一複雜了,他們的執行計畫就可能不一樣,這個時候就要我們去解決這些問題。這裡,我不會給你們講什麼情況下應該用

notin

什麼情況下應該用

notexists

,因為這些理論是沒用的,要具體情況具體分析。後面的章節我會講解半連線和反連線最底層的原理,把最底層原理搞懂之後,大家以後在遇到in和

exists

,not in

和notexists

就會迎刃而解了。

查詢 (反連線)

去重 交集 不忽略空值 select deptno from emp intersect select deptno from dept2 dept2 不在 emp表中的資料 select deptno from dept2 minus select deptno from emp select d...

SQL反模式筆記16 模糊查詢

目標 模糊查詢 反模式 like 缺點 效能太差,無法使用索引,必須全表遍歷。合理使用反模式 資料量小 條件簡單時可以用。解決方案 使用特殊的搜尋引擎而不是sql 1 資料庫擴充套件,各大資料庫都有對全文檢索的解決方案,但是配置複雜。2 使用第三方搜尋引擎,比如lucene.3 實現自己的搜尋引擎 ...

mysql 連線 優化 (一)MySQL 連線優化

1.檢視連線引數 show variables mysql show variables like connect variable name value character set connection utf8 collation connection utf8 general ci conne...