天天看點

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,一定要記得去重,這裡也給了我們一個思路,當你看到SQL是innerjoin,并且用了distinct,并且隻從一個表中取資料,可以将這類SQL寫成半連接配接,避免distinct排序,提升性能。

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

15 半連接配接(semi-join)--優化主題系列

繼續閱讀