15 半連線(semi-join)--優化主題系列
半連線(semi-join)
半連線是指兩個表/結果集做JOIN,但是隻返回某一個表/結果集中的資料。
執行計劃中,看到有NESTED LOOPS SEMI/HASH JOIN SEMI 就表示有半連線
比如下面的SQL(基於HROracle11gR2)
select department_name
from hr.departments dept
where department_id IN (select department_id from hr.employeesemp)
該SQL是departments表和employees表進行JOIN,但是隻返回departments表中的資料。
他們肯定在網上看到過相關的理論,in可以被exists代替,現在用exists改寫
select department_name
from hr.departments dept
where EXISTS (select null from hr.employees emp
where emp.department_id = dept.department_id);
我們還可以用join改寫這個SQL
select distinct department_name
from hr.departments dept, hr.employees emp
where dept.department_id = emp.department_id;
這種寫法就是亂寫,in裡巢狀連線。exists裡是可以的。
select department_name
from hr.departments dept
where department_id IN (select department_id from hr.employeesemp where emp.department_id = dept.department_id)
如果半連線改成JOIN 是不是有時候要寫DISTINCT關鍵字??
如果你們select 主鍵 from A... where 半連線
與主鍵JOIN
semi join SQL如果改寫為innerjoin,一定要記得去重,這裡也給了我們一個思路,當你看到
in和exists一般情況下執行計劃是一樣的,當SQL很複雜,用in或者是exists不同的寫法對效能就會產生巨大影響。