您的位置:首页 > 数据库 > Oracle

15 半连接(semi-join)--优化主题系列

2017-10-10 17:01 204 查看
半连接(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不同的写法对性能就会产生巨大影响。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息