作者:稀饭
在Oracle-SQL中,当一个子查询介于select和from之间时,这种子查询就叫做标量子查询,一个范例如下:
select a.name, a.sex,(select b.salary from salary b where b.deptno = a.deptno) salaryfrom user a;
标量子查询类似一个天然的嵌套循环,而且驱动表固定为主表。由于嵌套循环的被驱动表的连接列必须包含在索引中,所以标量子查询中的表连接也必须包含在索引中。
但实际工作中,应该尽量避免使用标量主查询。如果主表返回了大量数据,主表的连接列基数很高,那么子查询中的表也会被多次扫描,从而严重影响SQL的性能。如果主表的数据量很小,或者主表的连接基数很低,那么这个时候就可以使用标量主查询,但需要给子查询中的连接列建立索引。
当SQL里面有标量子查询时,可以将标量子查询改写为外连接,从而使它们可以进行Hash连接。之所以要把标量子查询改写为外连接而不是内连接的原因,是因为标量子查询是一个传值的过程,如果主表传值给子查询,子查询没有查询到数据,这个时候会显示NULL。此时将标量子查询改写为内连接,会丢失没有关联上的数据。下面是一个标量子查询:
select a.name, a.loc,(select max(b.sal) from table_2 b where b.deptno = a.deptno) max_salfrom table_1 a;
可以将其等价改写为外连接:
select a.name, a.loc, b.max_salfrom table_1 aleft join (select max(sal) max_sal, deptno from table_2 group by deptno) bon a.dept_no = b.deptno;
当然,如果主表的连接列是外键,而子查询的连接列是主键,则没有必要改写为外连接了,因为外键中不可能存在NULL值,可以直接改写为内连接。
广告区↓

文章转载自稀饭居然不在家,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




