测试数据:
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中子查询为聚合函数时的优化的更多相关文章

  1. SQL——连接查询、聚合函数、开窗函数、分组功能、联合查询、子查询

    连接查询 inner join,用的最多,表示多张表一一对应 聚合函数 操作行数据,进行合并 sum.avg.count.max.min 开窗函数 将合并的数据分布到原表的每一行,相当于多出来了一列, ...

  2. SQL分组查询及聚集函数的使用

    今天要做一个查询统计功能,一开始有点犯难,上午尝试大半天才写出统计sql语句,才发现自己sql分组查询及聚集函数没学好:其实就是group by子句和几个聚集函数,熟练使用统计功能很简单.在此总结下今 ...

  3. 【软件实施面试】MySQL和Oracle联合查询以及聚合函数面试总结

    软件实施面试系列文章第二弹,MySQL和Oracle联合查询以及聚合函数的面试总结.放眼望去全是MySQL,就不能来点Oracle吗?之前面过不少公司,也做过不少笔试题,现在已经很少做笔试题了.你肚子 ...

  4. sql server 2012 自定义聚合函数(MAX_O3_8HOUR_ND) 计算最大的臭氧8小时滑动平均值

    采用c#开发dll,并添加到sql server 中. 具体代码,可以用visual studio的向导生成模板. using System; using System.Collections; us ...

  5. SQL 数据库备、还,附、分,数据查询,聚合函数

    认识数据库备份和事务日志备份 数据库备份与日志备份是数据库维护的日常工作,备份的目的是在于当数据库出现故障或者遭到破坏时可以根据备份的数据库及事务日志文件还原到最近的时间点将损失降到最低点. 数据库备 ...

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

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

  7. sql sever模糊查询和聚合函数

    使用is null 的时候 要确保 查询的列 可以为空! null:  01.标识  空值  02.不是0,也不是空串""  03.只能出现在定义 允许为null的字段  04.只 ...

  8. SQL Server数据库————模糊查询和聚合函数

    ***********模糊查询*********/ 关键字: like (!!!!字符串类型) in (,,)  匹配()内的某个具体值(括号里可以写多个值) between... and.. 在某两 ...

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

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

随机推荐

  1. unix 网路编程(卷一)第一个程序编译过程

    unix卷一去年暑假买的到现在才开始看无比惭愧,而且惭愧第一个程序就断断续续弄了几天,要好好写程序了,马上要找工作了,下面介绍下把本书第一个程序跑起来的过程: 搜各种博客 我用系统的是ubuntu 1 ...

  2. 生产者/消费者问题的多种Java实现方式--转

    实质上,很多后台服务程序并发控制的基本原理都可以归纳为生产者/消费者模式,而这是恰恰是在本科操作系统课堂上老师反复讲解,而我们却视而不见不以为然的.在博文<一种面向作业流(工作流)的轻量级可复用 ...

  3. maven系列之二maven项目的创建和maven项目的结构

    maven系列之一简单介绍了maven的基本信息,安装和配置,大家对maven有一个大概的了解,但是在maven项目开发中远远不够,为了进一步了解maven,现在我们介绍maven项目的创建和mave ...

  4. 【转】使用BBB的device tree和cape(重新整理版)

    只要你想用BBB做哪怕一丁点涉及到硬件的东西,你就不可避免地要用到cape和device tree的知识.所以尽管它们看起来很陌生而且有点复杂,但还是得学.其实用起来不难的.下面我只讲使用时必须会的内 ...

  5. 动态修改 C 语言函数的实现

    Objective-C 作为基于 Runtime 的语言,它有非常强大的动态特性,可以在运行期间自省.进行方法调剂.为类增加属性.修改消息转发链路,在代码运行期间通过 Runtime 几乎可以修改 O ...

  6. MySQL(7):数值类型

    1. 数值类型  

  7. 关于SWT中的布局Layout

    组件装在容器里,那么这些组件是如何布局的呢?在这之前所有的例子都是使用setBounds来 进行绝对坐标的定位的. 在实际应用过程中大都是采用布局管理器的方式来布局容器中的组件. 布局管理器定义了组件 ...

  8. jquery checkbox全选,全不选,反选方法,jquery checkbox全选只能操作一次

    jquery checkbox全选,全不选,反选方法, jquery checkbox全选只能操作一次, jquery checkbox全选只有第一次成功 >>>>>&g ...

  9. monkey与monkeyrunner的使用

    什么是Monkey Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输入.手势输入等),实现对正在开发的应用程序进行压 ...

  10. css实现带箭头选项卡

    这阵子在做一个web端项目中遇到一个问题,需要实现带箭头的选项卡点击可切换.起初没想太多,直接切一个向上的小箭头图片,外层div设置相同颜色的边框,再用相对定位和绝对定位.这种方法是可行的,但是因为手 ...