值得反复研读的表连接之SCALAR SUBQUERY 方式

本文探讨了标量子查询的概念及其在SQL查询中的应用。解释了为何在特定情况下应避免使用标量子查询,尤其是当主表数据量大且连接列基数高时,这可能严重影响查询性能。同时,建议将标量子查询转换为外连接以提高效率,并通过实例展示了如何进行转换。最后,强调了考虑索引优化和查询改写对于提升SQL性能的重要性。
摘要由CSDN通过智能技术生成

当一个子查询介于select 与from之间,这种子查询就叫标量子查询。

select e.ename,
       e.sal,
       (select d.dname from dept d where d.deptno = e.deptno) dname
  from emp e;

scott@orclpdb1:orclcdb> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  5123bdvqcrffd, child number 0
-------------------------------------
select /*+gather_plan_statistics*/ e.ename,        e.sal,
(select d.dname from dept d where d.deptno = e.deptno) dname   from emp
e

Plan hash value: 2981343222

-------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------------

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |      1 |        |     14 |00:00:00.01 |       8 |
|   1 |  TABLE ACCESS BY INDEX ROWID| DEPT    |      3 |      1 |      3 |00:00:00.01 |       5 |
|*  2 |   INDEX UNIQUE SCAN         | PK_DEPT |      3 |      1 |      3 |00:00:00.01 |       2 |
|   3 |  TABLE ACCESS FULL          | EMP     |      1 |     14 |     14 |00:00:00.01 |       8 |
-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("D"."DEPTNO"=:B1)


22 rows selected.

scott@orclpdb1:orclcdb>

尽量避免使用标量子查询,假如主表示返回大量数据,主表的连接列基数很高,那么子查询中的表会被多次扫描,从而严重影响SQL性能。如果主表数据量小,或者主表的连接列基数很低,那么这个时候我们也可以使用标量子查询,但要记得要给子查询中表的连接列建立索引。

Q: 如何优化SQL中标量子查询

可以将标量子查询等价改写为外连接,从而使它们可以进行HASH连接。

Q:为什么要将标量子查询改写为外连接而不是内连接呢?

因为标量子查询是一个传值的过程,如果主表传值给子查询,子查询没有查询到数据,这个时候会显示NULL。如果将标量子查询改写为内连接,会丢失没有关联上的数据。

scott@orclpdb1:orclcdb> select d.dname,
  2         d.loc,
       (select max(e.sal) from emp e where e.deptno = d.deptno) max_sal
  4    from dept d;

DNAME          LOC              MAX_SAL
-------------- ------------- ----------
ACCOUNTING     NEW YORK            5000
RESEARCH       DALLAS              3000
SALES          CHICAGO             2850
OPERATIONS     BOSTON

4 rows selected.

scott@orclpdb1:orclcdb> select d.dname, d.loc, e.max_sal
  2    from dept d
  left join (select max(sal) max_sal, deptno from emp group by deptno) e
  4      on d.deptno = e.deptno;

DNAME          LOC              MAX_SAL
-------------- ------------- ----------
ACCOUNTING     NEW YORK            5000
RESEARCH       DALLAS              3000
SALES          CHICAGO             2850
OPERATIONS     BOSTON

4 rows selected.

scott@orclpdb1:orclcdb> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值