测试数据:
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. Servlet, Listener 、 Filter.

    Java Web的三大组件:Servlet, Listener . Filter. 使用Listener监听器:八大监听器: 第一组:用于监听Servlet三个域对象的创建与销毁 1. Servlet ...

  2. Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素

    Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...

  3. Java基础知识强化之网络编程笔记12:TCP之TCP协议上传文本文件并给出反馈

    1. 客户端: package cn.itcast_12; import java.io.BufferedReader; import java.io.BufferedWriter; import j ...

  4. case,cast

    UPDATE dbo.Dat_Camera SET Cam_Config='<xml><cam><type>2</type>'+CASE WHEN Ca ...

  5. 【MINA】用protobuf做编解码协议

    SOCKET协议 支持java serial 与 AMF3的混合协议,目前没有基于xml 与 json的实现. 协议说明: * 9个字节协议头+协议体. * * 协议头1-4字节表示协议长度 =协议体 ...

  6. Extjs combo赋值与刷新的先后顺序

    今天在跟一个弹出框中的多选下拉框赋值并实现反选的时候.惊讶的发现:原来我之前对于Combo的赋值的认知观是错误的. 我开始在窗体的beforeshow事件中对Combo控件赋值.开始使用了setVal ...

  7. Sql Server Profiler保存与重演跟踪

    重演跟踪的作用 可以将一个跟踪当做测试工具,当按照正确的顺序调用某些存储过程是肯能会重新生成特定的故障. 跟踪模板

  8. Objective-C 学习笔记(Day 3,上)

    ------------------------------------------- 类方法   ①类方法:        + 开头的方法(定义的过程形式和对象方法一样,只不过 + 开头,这是唯一的 ...

  9. Android笔记之adb命令应用实例1(手机端与PC端socket通讯上)

    Android端的代码: 布局文件:activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/ ...

  10. Java多线程练习:ticket卖票程序

    /*需求:简单的卖票程序多个窗口买票 */ class Ticket extends Thread{    private static int tick=100;    public void ru ...