1. 程式人生 > >15 半連線(semi-join)--優化主題系列

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)

SQLdepartments表和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,一定要記得去重,這裡也給了我們一個思路,當你看到

SQLinnerjoin,並且用了distinct,並且只從一個表中取資料,可以將這類SQL寫成半連線,避免distinct排序,提升效能。

inexists一般情況下執行計劃是一樣的,當SQL很複雜,用in或者是exists不同的寫法對效能就會產生巨大影響。