天天看点

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)--优化主题系列

继续阅读