半連接配接(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,一定要記得去重,這裡也給了我們一個思路,當你看到SQL是innerjoin,并且用了distinct,并且隻從一個表中取資料,可以将這類SQL寫成半連接配接,避免distinct排序,提升性能。
in和exists一般情況下執行計劃是一樣的,當SQL很複雜,用in或者是exists不同的寫法對性能就會産生巨大影響。