SQL中子查询为聚合函数时的优化
测试数据:
create table test1 as select * from dba_objects where rownum<=10000;--10000条记录
create table test2 as select * from dba_objects;--13438条记录
分析执行计划:
SQL1:
SQL> select *
2 from test
3 where object_id =
4 (select max(object_id)
5 from test1
6 where test1.object_name = test.object_name);
已选择10行。
已用时间: 00: 00: 00.07
执行计划
----------------------------------------------------------
Plan hash value: 2637409915
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 961 | 194K| 43 (0)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL | TEST | 10 | 2070 | 3 (0)| 00:00:01 |
| 3 | SORT AGGREGATE | | 1 | 79 | | |
|* 4 | TABLE ACCESS FULL| TEST1 | 96 | 7584 | 40 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_ID"= (SELECT MAX("OBJECT_ID") FROM "TEST1"
"TEST1" WHERE "TEST1"."OBJECT_NAME"=:B1))
4 - filter("TEST1"."OBJECT_NAME"=:B1)
Note
-----
- dynamic sampling used for this statement (level=4)
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
1344 consistent gets
0 physical reads
0 redo size
1710 bytes sent via SQL*Net to client
415 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
SQL2:
SQL> select *
2 from test
3 where exists (select 1
4 from (select distinct object_name,
5 max(object_id) over(partition by test1.object_name) object_id
6 from test1) t
7 where t.object_name = test.object_name
8 and test.object_id = t.object_id);
已选择10行。
已用时间: 00: 00: 00.06
执行计划
----------------------------------------------------------
Plan hash value: 918945524
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 286 | | 405 (1)| 00:00:05 |
|* 1 | HASH JOIN SEMI | | 1 | 286 | | 405 (1)| 00:00:05 |
| 2 | TABLE ACCESS FULL | TEST | 10 | 2070 | | 3 (0)| 00:00:01 |
| 3 | VIEW | | 9606 | 741K| | 401 (1)| 00:00:05 |
| 4 | HASH UNIQUE | | 9606 | 741K| 848K| 401 (1)| 00:00:05 |
| 5 | WINDOW SORT | | 9606 | 741K| 848K| 401 (1)| 00:00:05 |
| 6 | TABLE ACCESS FULL| TEST1 | 9606 | 741K| | 40 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T"."OBJECT_NAME"="TEST"."OBJECT_NAME" AND
"TEST"."OBJECT_ID"="T"."OBJECT_ID")
Note
-----
- dynamic sampling used for this statement (level=4)
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
137 consistent gets
0 physical reads
0 redo size
1710 bytes sent via SQL*Net to client
415 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
10 rows processed 从上面执行计划可以看出:
SQL1:filter会根据test返回行数决定过滤表test1访问次数,类似于nested loop(注意,第二个表总是全表扫描的哦);逻辑读也比较大1344.
SQL2:相当于将子查询作为一个”表“与test进行hash join,当然每个表只会访问一次。逻辑读为137。
当然,如果test表返回数据量很大,那么SQL1的效率问题会更明显。
这个就属于SQL书写的问题,需要谨慎小心。 将子查询作为一个“表”与主查询表test做join连接,当然,需要先改写max聚合函数为分析函数,如下:
select *
from test
join (select object_name, max(object_id) object_id
from test1
group by object_name) t
on test.object_name = t.object_name
and test.object_id = t.object_id;
与上面改写是等效的。
SQL中子查询为聚合函数时的优化的更多相关文章
- SQL——连接查询、聚合函数、开窗函数、分组功能、联合查询、子查询
连接查询 inner join,用的最多,表示多张表一一对应 聚合函数 操作行数据,进行合并 sum.avg.count.max.min 开窗函数 将合并的数据分布到原表的每一行,相当于多出来了一列, ...
- SQL分组查询及聚集函数的使用
今天要做一个查询统计功能,一开始有点犯难,上午尝试大半天才写出统计sql语句,才发现自己sql分组查询及聚集函数没学好:其实就是group by子句和几个聚集函数,熟练使用统计功能很简单.在此总结下今 ...
- 【软件实施面试】MySQL和Oracle联合查询以及聚合函数面试总结
软件实施面试系列文章第二弹,MySQL和Oracle联合查询以及聚合函数的面试总结.放眼望去全是MySQL,就不能来点Oracle吗?之前面过不少公司,也做过不少笔试题,现在已经很少做笔试题了.你肚子 ...
- sql server 2012 自定义聚合函数(MAX_O3_8HOUR_ND) 计算最大的臭氧8小时滑动平均值
采用c#开发dll,并添加到sql server 中. 具体代码,可以用visual studio的向导生成模板. using System; using System.Collections; us ...
- SQL 数据库备、还,附、分,数据查询,聚合函数
认识数据库备份和事务日志备份 数据库备份与日志备份是数据库维护的日常工作,备份的目的是在于当数据库出现故障或者遭到破坏时可以根据备份的数据库及事务日志文件还原到最近的时间点将损失降到最低点. 数据库备 ...
- 【2017-03-12】SQL Sever 子查询、聚合函数
一.子查询 子查询:把一条查询语句,当做值来使用子句的查询结果必须是一列子句可以返回多行数据,但必须是一列 子句返回的值为一个值的时候: 例如: 我只知道c026这个编号,我要查询比这个车价格低的全部 ...
- sql sever模糊查询和聚合函数
使用is null 的时候 要确保 查询的列 可以为空! null: 01.标识 空值 02.不是0,也不是空串"" 03.只能出现在定义 允许为null的字段 04.只 ...
- SQL Server数据库————模糊查询和聚合函数
***********模糊查询*********/ 关键字: like (!!!!字符串类型) in (,,) 匹配()内的某个具体值(括号里可以写多个值) between... and.. 在某两 ...
- 18 12 06 sql 的 基本语句 查询 条件查询 逻辑运算符 模糊查询 范围查询 排序 聚合函数 分组 分页 连接查询 自关联 子查询
-- 数据的准备 -- 创建一个数据库 create database python_test charset=utf8; -- 使用一个数据库 use python_test; -- 显示使用的当前 ...
随机推荐
- nginx---reference
nginx (pronounced "engine x") is a free open source web server written by Igor Sysoev, a R ...
- Helpers\Assets
Helpers\Assets The assets helper is for loading CSS and JS files rather than writing out the full sc ...
- 深入学习block
首先,什么是block?block其实就是一个代码块,把你想要执行的代码封装在这个代码块里,等到需要的时候再去调用.那block是OC对象吗?答案是肯定的. 做一道很简单的关于block的测试题: i ...
- Android版本控制系统及其间的差异
一.何谓版本控制 它是一种软件工程籍以在开发的过程中,确保由不同人所编辑的同一档案都得到更新,它透过文档控制记录程序各个模块的改动,并为每次改动编上序号,并且编辑错误之后还可以回溯到以前的版本 二.可 ...
- ios知识点
在controller中加载plist数据 1,设置属性NSArray 或可变数组NSMutableArray @property(nonatomic,strong)NSArray *message; ...
- CentOS7安装RabbitMQ集群
实验环境 RabbitMQ 集群 server1.example.com IP: 10.10.10.11 Node: diskserver2.example.com IP: 10.1 ...
- spring+ibatis环境搭建
简单的spring+ibatis入门实例:ibatis是一种半自动化的持久层框架,它介于JDBC和hibernate之间,使用比较灵活. 一:目录结构 二:需要导入的jar包: 所有的第三方jar包都 ...
- Fedora 19修改主机名
Distribution为Fedora 19 方式一(重启后失效,需root权限): hostname 新主机名 [root@promote hadoop]# hostname promote.cac ...
- 关于工作流之最后Assign给TeamLeader
如果你的单子Buddy验证通过了.然后也进行了Integrate了,然后就可以把这个单子给TL(Team Leader)了. >>>>>>>>>& ...
- dirname(__FILE__) 的使用总结
dirname(__FILE__) php中定义了一个很有用的常数,即 __file__ 这个内定常数是当前php程序的就是完整路径(路径+文件名). 即使这个文件被其他文件引用(include或re ...