SQL优化之四两拨千金
MIS惯用分页,有的时候关联的表都非常大。如下所示的SQL,如果按照如下形式写,则会造成全表扫描。
原始SQL:
SQL> SELECT *
FROM (SELECT INNER_TABLE.*, ROWNUM OUTER_TABLE_ROWNUM
FROM (SELECT GAC.CONFIRM_ID,
GAC.CONFIRM_NAME,
GAC.CONFIRM_DATE,
GAC.BUREAU_ID,
GAC.BUREAU_NAME,
GAC.CREATOR_ID,
GAC.CREATOR,
GAC.CREATE_DATE,
GAC.STATUS,
GAC.BID_TARGET,
GAC.MEETING_MINUTES,
GAC.F1,
GAC.F2,
GAC.REMARK,
GAC.VALIDATE_FLAG,
GAC.READ_FLAG,
GAC.BACK_FLAG,
GAC.CONFIRM_TYPE,
GAC.DATA_AREA,
GAC.PROJECT_ID,
GAC.PROJECT_NAME,
GAC.SUBPROJECT_ID,
GAC.SUBPROJECT_NAME,
GAC.OLD_CONFIRM_ID,
GAC.CONFIRM_CHANGE_REASON,
GAC.IS_STATISTIC,
GAC.UPDATE_FLAG,
GAC.AVOID_DUTY_REASON,
GAC.LOCAL_PROJECT_CODE,
GAC.UNIQUE_PROJECT_CODE,
MAX(GACI.REQUIREMENT_ID) AS REQUIREMENT_ID
FROM GG_ASSIGNMENT_CONFIRM GAC, GG_ASSIGNMENT_CONFIRM_ITEM GACI
WHERE GAC.CONFIRM_ID = GACI.CONFIRM_ID(+)
AND GAC.CREATE_DATE >= TO_DATE('2016-09-04', 'yyyy-mm-dd')
AND GAC.CREATE_DATE < TO_DATE('2017-09-04', 'yyyy-mm-dd') + (INTERVAL '1' DAY)
GROUP BY GAC.CONFIRM_ID,
GAC.CONFIRM_NAME,
GAC.CONFIRM_DATE,
GAC.BUREAU_ID,
GAC.BUREAU_NAME,
GAC.CREATOR_ID,
GAC.CREATOR,
GAC.CREATE_DATE,
GAC.STATUS,
GAC.BID_TARGET,
GAC.MEETING_MINUTES,
GAC.F1,
GAC.F2,
GAC.REMARK,
GAC.VALIDATE_FLAG,
GAC.READ_FLAG,
GAC.BACK_FLAG,
GAC.CONFIRM_TYPE,
GAC.DATA_AREA,
GAC.PROJECT_ID,
GAC.PROJECT_NAME,
GAC.SUBPROJECT_ID,
GAC.SUBPROJECT_NAME,
GAC.OLD_CONFIRM_ID,
GAC.CONFIRM_CHANGE_REASON,
GAC.IS_STATISTIC,
GAC.UPDATE_FLAG,
GAC.AVOID_DUTY_REASON,
GAC.LOCAL_PROJECT_CODE,
GAC.UNIQUE_PROJECT_CODE
ORDER BY GAC.CONFIRM_TYPE ASC NULLS LAST) INNER_TABLE
WHERE ROWNUM <=25) OUTER_TABLE
WHERE OUTER_TABLE_ROWNUM >0;
已选择25行。
已用时间: 00: 00: 30.58
执行计划
----------------------------------------------------------
Plan hash value: 1427996981
-------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 109K| | 160K (1)| 00:32:06 | | |
|* 1 | VIEW | | 25 | 109K| | 160K (1)| 00:32:06 | | |
|* 2 | COUNT STOPKEY | | | | | | | | |
| 3 | VIEW | | 589K| 2512M| | 160K (1)| 00:32:06 | | |
|* 4 | SORT GROUP BY STOPKEY | | 589K| 196M| 209M| 160K (1)| 00:32:06 | | |
|* 5 | HASH JOIN OUTER | | 589K| 196M| 32M| 116K (1)| 00:23:17 | | |
| 6 | PARTITION RANGE ITERATOR| | 105K| 31M| | 3310 (1)| 00:00:40 | 7 | 8 |
| 7 | PARTITION LIST ALL | | 105K| 31M| | 3310 (1)| 00:00:40 | 1 | 27 |
|* 8 | TABLE ACCESS FULL | GG_ASSIGNMENT_CONFIRM | 105K| 31M| | 3310 (1)| 00:00:40 | 163 | 216 |
| 9 | PARTITION RANGE ALL | | 3276K| 112M| | 103K (1)| 00:20:48 | 1 |1048575|
| 10 | PARTITION LIST ALL | | 3276K| 112M| | 103K (1)| 00:20:48 | 1 | 27 |
| 11 | TABLE ACCESS FULL | GG_ASSIGNMENT_CONFIRM_ITEM | 3276K| 112M| | 103K (1)| 00:20:48 | 1 |1048575|
-------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OUTER_TABLE_ROWNUM">0)
2 - filter(ROWNUM<=25)
4 - filter(ROWNUM<=25)
5 - access("GAC"."CONFIRM_ID"="GACI"."CONFIRM_ID"(+))
8 - filter("GAC"."CREATE_DATE">=TO_DATE(' 2016-09-04 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"GAC"."CREATE_DATE"<TO_DATE(' 2017-09-05 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
374591 consistent gets
307518 physical reads
14208 redo size
6776 bytes sent via SQL*Net to client
483 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
25 rows processed
优化后:四两拨千金就是先把主表的数据先查出25条,然后跟从表关联,这是一种很重要的优化思路。
SQL> with GAC as (SELECT *
FROM (SELECT INNER_TABLE.*, ROWNUM OUTER_TABLE_ROWNUM
FROM (SELECT GAC.CONFIRM_ID,
GAC.CONFIRM_NAME,
GAC.CONFIRM_DATE,
GAC.BUREAU_ID,
GAC.BUREAU_NAME,
GAC.CREATOR_ID,
GAC.CREATOR,
GAC.CREATE_DATE,
GAC.STATUS,
GAC.BID_TARGET,
GAC.MEETING_MINUTES,
GAC.F1,
GAC.F2,
GAC.REMARK,
GAC.VALIDATE_FLAG,
GAC.READ_FLAG,
GAC.BACK_FLAG,
GAC.CONFIRM_TYPE,
GAC.DATA_AREA,
GAC.PROJECT_ID,
GAC.PROJECT_NAME,
GAC.SUBPROJECT_ID,
GAC.SUBPROJECT_NAME,
GAC.OLD_CONFIRM_ID,
GAC.CONFIRM_CHANGE_REASON,
GAC.IS_STATISTIC,
GAC.UPDATE_FLAG,
GAC.AVOID_DUTY_REASON,
GAC.LOCAL_PROJECT_CODE,
GAC.UNIQUE_PROJECT_CODE
FROM GG_ASSIGNMENT_CONFIRM GAC
WHERE GAC.CREATE_DATE >= TO_DATE('2016-09-04', 'yyyy-mm-dd')
AND GAC.CREATE_DATE < TO_DATE('2017-09-04', 'yyyy-mm-dd') + (INTERVAL '1' DAY)
order by GAC.CREATE_DATE desc) INNER_TABLE
WHERE ROWNUM <=25) OUTER_TABLE
WHERE OUTER_TABLE_ROWNUM >0)
select * from (select GAC.*,
row_number() over(partition by GAC.Confirm_Id order by REQUIREMENT_ID desc) rn,
GACI.REQUIREMENT_ID AS REQUIREMENT_ID
FROM GAC, GG_ASSIGNMENT_CONFIRM_ITEM GACI
WHERE GAC.CONFIRM_ID = GACI.CONFIRM_ID) where rn=1
order by CREATE_DATE desc;
已选择25行。
已用时间: 00: 00: 00.04
执行计划
----------------------------------------------------------
Plan hash value: 1757804957
-----------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 140 | 614K| 112 (2)| 00:00:02 | | |
| 1 | SORT ORDER BY | | 140 | 614K| 112 (2)| 00:00:02 | | |
|* 2 | VIEW | | 140 | 614K| 111 (1)| 00:00:02 | | |
|* 3 | WINDOW SORT PUSHED RANK | | 140 | 614K| 111 (1)| 00:00:02 | | |
| 4 | NESTED LOOPS | | 140 | 614K| 110 (0)| 00:00:02 | | |
|* 5 | VIEW | | 25 | 108K| 10 (0)| 00:00:01 | | |
|* 6 | COUNT STOPKEY | | | | | | | |
| 7 | VIEW | | 25 | 108K| 10 (0)| 00:00:01 | | |
| 8 | TABLE ACCESS BY GLOBAL INDEX ROWID| GG_ASSIGNMENT_CONFIRM | 105K| 31M| 10 (0)| 00:00:01 | ROWID | ROWID |
|* 9 | INDEX RANGE SCAN DESCENDING | INDEX_CREATE_DATE_AC_12 | 25 | | 3 (0)| 00:00:01 | | |
| 10 | TABLE ACCESS BY GLOBAL INDEX ROWID | GG_ASSIGNMENT_CONFIRM_ITEM | 6 | 216 | 4 (0)| 00:00:01 | ROWID | ROWID |
|* 11 | INDEX RANGE SCAN | IDX_GG_ASS_CONF_ID_12 | 6 | | 2 (0)| 00:00:01 | | |
-----------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("RN"=1)
3 - filter(ROW_NUMBER() OVER ( PARTITION BY "OUTER_TABLE"."CONFIRM_ID" ORDER BY INTERNAL_FUNCTION("GACI"."REQUIREMENT_ID")
DESC )<=1)
5 - filter("OUTER_TABLE_ROWNUM">0)
6 - filter(ROWNUM<=25)
9 - access("GAC"."CREATE_DATE">=TO_DATE(' 2016-09-04 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "GAC"."CREATE_DATE"<TO_DATE('
2017-09-05 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
11 - access("OUTER_TABLE"."CONFIRM_ID"="GACI"."CONFIRM_ID")
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
295 consistent gets
0 physical reads
0 redo size
8139 bytes sent via SQL*Net to client
483 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
25 rows processed
SQL优化之四两拨千金相关推荐
- postgresql两个列模糊比较_数据分析之SQL优化系列(二)---PostgreSQL 的索引
参考<PostgreSQL11.2-中文手册> 下面这个链接,讲的通俗易懂,可以看看. 数据分析师不得不知道的SQL优化 - 鑫获 - 博客园www.cnblogs.com 索引是提高数 ...
- 中秋节,送上一次非常有趣的SQL优化实战经历
点击上方"搜云库技术团队",选择"设为星标" 回复"1024"或"面试题"获取4T学习资料 补充:看到好多朋友后台留言说 ...
- 5大步骤+10个案例,堪称SQL优化万能公式
作者丨狼爷 来源丨网址:https://www.cnblogs.com/powercto/p/14410128.html 一.前言 在应用开发的早期,数据量少,开发人员开发功能时更重视功能上的实现,随 ...
- 15 种 SQL 优化中,老司机才懂的处理技巧
前言 SQL优化是一个大家都比较关注的热门话题,无论你在面试,还是工作中,都很有可能会遇到. 如果某天你负责的某个线上接口,出现了性能问题,需要做优化.那么你首先想到的很有可能是优化SQL语句,因为它 ...
- 面试官:不会看 Explain执行计划,简历敢写 SQL 优化?
来自:程序员内点事 昨天中午在食堂,和部门的技术大牛们坐在一桌吃饭,作为一个卑微技术渣仔默默的吃着饭,听大佬们高谈阔论,研究各种高端技术,我TM也想说话可实在插不上嘴. 聊着聊着突然说到他上午面试了一 ...
- 大牛是怎么思考设计SQL优化方案的?
作者:惨绿少年 https://www.cnblogs.com/clsn/p/8214048.html 在进行MySQL的优化之前,必须要了解的就是MySQL的查询过程,很多查询优化工作实际上就是遵循 ...
- 刘铁岩:如何四两拨千斤,高效地预训练NLP模型?
智源社区 & AI科技评论 作者 | 熊宇轩 智源导读:2020 年 11 月 1 日,微软亚洲研究院副院长.IEEE会士.ACM杰出科学家刘铁岩博士在第十九届中国计算语言学大会(CCL)上发 ...
- 数据库 SQL 优化大总结之:百万级数据库优化方案
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...
- SQL优化|Java面试题
看到一篇非常全面的SQL优化文章,在开发的工作中往往不考虑性能上的缺失(在一开始的时候数据量不大也看不出速度上的区别).但写的越多越应该规范一下写法. 原文链接:http://www.jfox.inf ...
最新文章
- 用MFC类来操作数据库的方法
- 全球及中国箱包市场需求前景与投资动态分析报告2022版
- Winforn中设置ZedGraph多条Y轴时曲线刻度不均匀问题解决
- matlab实现音频信号的左右声道信号分离_立体声分离度与立体声相关系数
- 牛顿迭代法(Newton#39;s Method)
- python获取方法的装饰方法_python中的方法和装饰器
- Java File类File [] listFiles()方法(带示例)
- mysql safe 模式_MYSQL的安全模式:sql_safe_updates介绍
- Linux chapter 7
- 中心极限定理_达尔文的进化论正确吗?
- 知网论文复制格式问题-文本修改器
- 人口各省预测模型matlab_MATLAB实验9河南省人口预测模型马尔萨斯人口模型.doc
- 使用librdkafka
- Life feelings--13--青春不毕业,那些心里念念叨叨难以忘怀的记忆
- Unity软件界面--Unity基本介绍
- Mysql基础篇(5)—— 约束
- 华三HCL免费下载体验
- 爬虫中使用selenium实现对斗鱼直播的各个房间标题、主播id,直播内容类型和热度信息的爬取
- RS232/RS485信号转12路模拟信号 隔离D/A转换器WJ34
- python sort 多级排序_python sort、sorted高级排序技巧