前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >优化一个rownum=1的sql

优化一个rownum=1的sql

作者头像
老虎刘
发布2022-06-22 17:53:59
发布2022-06-22 17:53:59
5620
举报

因为一直身体不适,挺长时间没写文章了,今天先写个简单的吧。

这是某个客户的BOSS系统中的一个top sql,SQL代码如下:

SELECT

t1.seq AS sequence

,t1.TemplateID AS templateId ,t1.parameter AS parameter

,t1.SERVICE_NO AS serviceNo ,trim(t1.phone_no) AS phoneNo

,to_char(t1.INSERT_TIME, 'yyyymmddhh24miss') AS insertTime

,t1.OP_CODE AS op_code ,t1.LOGIN_NO AS login_no

,t1.SERV_NO AS servNo ,t1.SERV_NAME AS servName

,to_char(t1.send_time, 'yyyymmddhh24mi') AS sendTime

,t1.SUB_PHONE_SEQ AS subPhoneNo

,t1.hold1 AS hold1 ,t1.hold2 AS hold2

,t1.hold3 AS hold3 ,t1.hold4 AS hold4

,t1.hold5 AS hold5

FROM PUSH_1_8610 t1

WHERE rownum <= : 1;

非常简单的一个SQL,每执行一次要消耗非常高的buffer gets,见下图:

执行计划是全表扫描:

-----------------------------------------------------------------------------------

| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |

-----------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | | | 1680 (100)| |

|* 1 | COUNT STOPKEY | | | | | |

| 2 | TABLE ACCESS FULL| PUSH_1_8610 | 1 | 2513 | 1680 (2)| 00:00:09 |

-----------------------------------------------------------------------------------

正常来讲,随便从一张表取一条记录,如果表的每个block都有数据,只需要读一次就可以返回了。但是,如果表的blocks数很多,但开始部分是空的(delete了),或者整张表的记录都被delete了,那么就需要把整张表都扫描完才行。

这张表就是这样的,16471个blocks,0条记录。

针对这种sql,可以借助index的hint一招搞定,但是有个要求就是,表上这个index用到的字段必须有一个定义是not null,符合这样的索引随便找一个就行。 这样就不用走全表扫描了。

这个表有个主键:PK_PUSH_1_8610,那优化后的SQL就变成了:

SELECT /*+ index(t1 PK_PUSH_1_8610) */

t1.seq AS sequence

,t1.TemplateID AS templateId ,t1.parameter AS parameter

,t1.SERVICE_NO AS serviceNo ,trim(t1.phone_no) AS phoneNo

,to_char(t1.INSERT_TIME, 'yyyymmddhh24miss') AS insertTime

,t1.OP_CODE AS op_code ,t1.LOGIN_NO AS login_no

,t1.SERV_NO AS servNo ,t1.SERV_NAME AS servName

,to_char(t1.send_time, 'yyyymmddhh24mi') AS sendTime

,t1.SUB_PHONE_SEQ AS subPhoneNo

,t1.hold1 AS hold1 ,t1.hold2 AS hold2

,t1.hold3 AS hold3 ,t1.hold4 AS hold4

,t1.hold5 AS hold5

FROM PUSH_1_8610 t1

WHERE rownum <= : 1;

加了这个hint后,不管表的数据如何变化,都会在几毫秒内返回结果。

今天刚刚看到公司内一位老前辈写的一篇文章,讲到慎用hint。大方向是对的,但是,有些sql还是需要hint来进行优化,这个SQL就是个例子。

我之前的一些公众号文章也有一些SQL是需要hint来优化的。尤其在很多谓词条件复杂或者关联条件复杂的情况下,靠统计信息是没有办法对行源进行准确估值的,这个时候就必须借助hint来帮助优化器制定一个良好的执行计划。作为一个高级DBA或是开发人员,hint还是需要掌握的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-10-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老虎刘谈oracle性能优化 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档