标量子查询的语句:

select /*+ GATHER_PLAN_STATISTICS  dwtest */ empno,
(select count(*) from DEPT1 b where b.id = a.id) as d,
(select sum(x) from DEPT1 b where b.id = a.id) as e
from EMP1 a --where a.id in (1,2,3,4,5,6,7,8,9,11,12,13) 

创建表:

create table DEPT1 as select  * from DEPT;
insert into DEPT1 select * from DEPT1; ---多执行几次 create table emp1 as select * from emp;
insert into emp1 select * from emp1; ---多执行几次 alter table DEPT1 add id number;
update DEPT1 set id=rownum; alter table emp1 add id number;
update emp1 set id=rownum;
create index idx_emp1 on emp1(id);

create index idx_DEPT1 on dept1(id);

改写后的语句:

select /*+ GATHER_PLAN_STATISTICS  dwtes2 */ empno,d,e from EMP1 a
left join (select count(1)d,id,sum(x) e from DEPT1 group by id) b on a.id=b.id --where a.id in (1,2,3,4,5,6,7,8,9,11,12,13);

  在放开where条件时,标量子查询时的多次索引范围扫描,导致cost较高,性能比左连接方式要差些,从下图看的不是很明显,如果从monitor看耗时更直观些。得出结论是:左连接改写后效率比标量子查询稍好,但是没有明显提升。

----
SQL_ID 8mgcw7x9x16rq, child number 0
-------------------------------------
select /*+ GATHER_PLAN_STATISTICS dwtest */ empno, (select
count(*) from DEPT1 b where b.id = a.id) as d, (select sum(x)
from DEPT1 b where b.id = a.id) as e from EMP1 a where a.id in
(1,2,3,4,5,6,7,8,9,11,12,13) Plan hash value: 3470857716 -------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 12 |00:00:00.01 | 9 | 4 |
| 1 | SORT AGGREGATE | | 12 | 1 | 12 |00:00:00.01 | 8 | 1 |
|* 2 | INDEX RANGE SCAN | IDX_DEPT1 | 12 | 1 | 12 |00:00:00.01 | 8 | 1 |
| 3 | SORT AGGREGATE | | 12 | 1 | 12 |00:00:00.01 | 10 | 0 |
| 4 | TABLE ACCESS BY INDEX ROWID| DEPT1 | 12 | 1 | 12 |00:00:00.01 | 10 | 0 |
|* 5 | INDEX RANGE SCAN | IDX_DEPT1 | 12 | 1 | 12 |00:00:00.01 | 8 | 0 |
| 6 | INLIST ITERATOR | | 1 | | 12 |00:00:00.01 | 9 | 4 |
| 7 | TABLE ACCESS BY INDEX ROWID| EMP1 | 12 | 12 | 12 |00:00:00.01 | 9 | 4 |
|* 8 | INDEX RANGE SCAN | IDX_EMP1 | 12 | 12 | 12 |00:00:00.01 | 8 | 4 |
------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("B"."ID"=:B1)
5 - access("B"."ID"=:B1)
8 - access(("A"."ID"=1 OR "A"."ID"=2 OR "A"."ID"=3 OR "A"."ID"=4 OR "A"."ID"=5 OR "A"."ID"=6 OR
"A"."ID"=7 OR "A"."ID"=8 OR "A"."ID"=9 OR "A"."ID"=11 OR "A"."ID"=12 OR "A"."ID"=13)) -----
SQL_ID dpwyqsf1rch2g, child number 0
-------------------------------------
select /*+ GATHER_PLAN_STATISTICS dwtes2 */ empno,d,e from EMP1 a left
join (select count(1)d,id,sum(x) e from DEPT1 group by id) b on
a.id=b.id where a.id in (1,2,3,4,5,6,7,8,9,11,12,13) Plan hash value: 1193336691 ----------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 12 |00:00:00.01 | 19 | | | |
|* 1 | HASH JOIN OUTER | | 1 | 12 | 12 |00:00:00.01 | 19 | 1969K| 1969K| 1407K (0)|
| 2 | INLIST ITERATOR | | 1 | | 12 |00:00:00.01 | 9 | | | |
| 3 | TABLE ACCESS BY INDEX ROWID | EMP1 | 12 | 12 | 12 |00:00:00.01 | 9 | | | |
|* 4 | INDEX RANGE SCAN | IDX_EMP1 | 12 | 12 | 12 |00:00:00.01 | 8 | | | |
| 5 | VIEW | | 1 | 12 | 12 |00:00:00.01 | 10 | | | |
| 6 | HASH GROUP BY | | 1 | 12 | 12 |00:00:00.01 | 10 | 1116K| 1116K| 2222K (0)|
| 7 | INLIST ITERATOR | | 1 | | 12 |00:00:00.01 | 10 | | | |
| 8 | TABLE ACCESS BY INDEX ROWID| DEPT1 | 12 | 12 | 12 |00:00:00.01 | 10 | | | |
|* 9 | INDEX RANGE SCAN | IDX_DEPT1 | 12 | 12 | 12 |00:00:00.01 | 8 | | | |
---------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - access("A"."ID"="B"."ID")
4 - access(("A"."ID"=1 OR "A"."ID"=2 OR "A"."ID"=3 OR "A"."ID"=4 OR "A"."ID"=5 OR "A"."ID"=6 OR "A"."ID"=7 OR
"A"."ID"=8 OR "A"."ID"=9 OR "A"."ID"=11 OR "A"."ID"=12 OR "A"."ID"=13))
9 - access(("ID"=1 OR "ID"=2 OR "ID"=3 OR "ID"=4 OR "ID"=5 OR "ID"=6 OR "ID"=7 OR "ID"=8 OR "ID"=9 OR "ID"=11 OR
"ID"=12 OR "ID"=13))

  在没有where条件时,上例的索引选择性非常好,标量子查询时的多次索引范围扫描,与左连接方式的对两表的全表扫描的hash排序cost差不多,导致两种方式效率相差无几。得出结论是:在关联索引选择性非常好时,左连接改写后效率比标量子查询差不多,但是如果索引选择性一般时,左连接效果要好。

  但是在关联条件没有索引时,emp1表多少行,就要对dept是乘2次的全表扫描,此时就会导致cost非常高。

所以,尽量使用左连接加分组来优化

标量子查询加聚合函数sql改写一的更多相关文章

  1. 【2017-03-12】SQL Sever 子查询、聚合函数

    一.子查询 子查询:把一条查询语句,当做值来使用子句的查询结果必须是一列子句可以返回多行数据,但必须是一列 子句返回的值为一个值的时候: 例如: 我只知道c026这个编号,我要查询比这个车价格低的全部 ...

  2. 标量子查询SQL改写

    一网友说下面sql跑的好慢,让我看看 sql代码: select er, cid, pid, tbl, zs, sy, (select count(sr.mobile_tele_no) from tb ...

  3. 18 12 06 sql 的 基本语句 查询 条件查询 逻辑运算符 模糊查询 范围查询 排序 聚合函数 分组 分页 连接查询 自关联 子查询

    -- 数据的准备 -- 创建一个数据库 create database python_test charset=utf8; -- 使用一个数据库 use python_test; -- 显示使用的当前 ...

  4. 优化有标量子查询的SQL

    数据库环境:SQL SERVER 2008R2 今天在数据库中抓出一条比较耗费资源的SQL,只返回904条数据,居然跑了40多分钟.SQL及对应的数据量如下图: SELECT saft04.cur_y ...

  5. SQL Server的优化器会缓存标量子查询结果集吗

    在这篇博客"ORACLE当中自定义函数性优化浅析"中,我们介绍了通过标量子查询缓存来优化函数性能: 标量子查询缓存(scalar subquery caching)会通过缓存结果减 ...

  6. [20180626]函数与标量子查询14.txt

    [20180626]函数与标量子查询14.txt --//前面看http://www.cnblogs.com/kerrycode/p/9099507.html链接,里面提到: 通俗来将,当使用标量子查 ...

  7. 标量子查询调优SQL

    fxnjbmhkk4pp4 select /*+ leading (wb,sb,qw) */ 'blocker('||wb.holding_session||':'||sb.username||')- ...

  8. Oracle sql优化之分析函数优化标量子查询

    待优化语句如下 select a.code as code, a.m_code as m_code,a.stktype as f_stype,a.e_year as e_year, b.sname a ...

  9. SQL优化-标量子查询(数据仓库设计的隐患-标量子查询)

    项目数据库集群出现了大规模节点宕机问题.经查询,问题在于几张表被锁.主要问题在于近期得几个项目在数据库SQL编写时大量使用了标量子查询. 为确定为题确实是由于数据表访问量超过单节点限制,做了一些测试. ...

  10. 【SQL基础】【记住重命名】高级查询:聚合函数(四舍五入)、分组过滤、排序、

    〇.概述 1.功能概述 高级查询:聚合函数(四舍五入).分组过滤.排序. 2.建表语句 drop table if exists user_profile; CREATE TABLE `user_pr ...

随机推荐

  1. 快速删除 node_modules

    node_modules 文件夹很大,不推荐右键通过回收站删除,通过 rimraf 来删除速度很快: # 安装 rimraf npm i -g rimraf # 删除 node_modules rim ...

  2. 基于Python的OpenGL 05 之坐标系统

    1. 引言 本文基于Python语言,描述OpenGL的坐标系统 前置知识可参考: 基于Python的OpenGL 04 之变换 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com) 笔者 ...

  3. rn项目启动时卡在Task :app:checkDebugAarMetadata

    原因是Gradle在下载依赖,打开Android Studio就可以看到右下角在下载.

  4. [转载]危险操作一追到底--Linux的历史记录

    转自:https://zhuanlan.zhihu.com/p/524921170 危险操作一追到底--Linux的历史记录 KellanFan 为了更好的自己     概述 在Linux下使用his ...

  5. Ubuntu命令安装默认支持的Qt5版本

    1.前置依赖 sudo apt install build-essential sudo apt install cmake 2.只安装默认的Qt模块 # 安装默认SDK # Ubuntu18.04中 ...

  6. vue3学习

    资料: http://docs.vikingship.xyz/ 声明类型:      1.使用ref可以声明基础数据 2.使用reactive声明对象数据 3.computed可以返回一个不变的响应式 ...

  7. []Linux 离线升级Openssh与Openssl版本

    https://blog.csdn.net/qq_45728838/article/details/120825845 离线的意思是为Linux无法链接网络,只能通过windows 将文件上传一.首先 ...

  8. 使用oledb读写excel出现“操作必须使用一个可更新的查询”的解决办法

    使用oledb读写excel出现"操作必须使用一个可更新的查询"的解决办法 转自:http://www.cnblogs.com/Richinger/archive/2008/09/ ...

  9. 【剑指Offer】【树】二叉搜索树的后序遍历序列

    题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. A:在二叉树的后序遍历中,数组最后一个元素为根节点,左 ...

  10. js通过hook拿fetch返回数据

    前言 很多情况下咱们在做浏览器插件的时候需要拿fetch的返回数据而不影响功能正常操作. 原理 hook原理咱就不讲了,跟其他hook差不多.具体来看看如何实现返回的. 用过fetch的朋友应该都知道 ...