前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 Order by 与 rownum SQL 优化案例一则

使用 Order by 与 rownum SQL 优化案例一则

作者头像
老虎刘
发布2022-06-22 17:30:44
4380
发布2022-06-22 17:30:44
举报
文章被收录于专栏:老虎刘谈oracle性能优化

这是某客户AWR报告中的一个TOP SQL,执行时间8.8小时(也有执行12.7小时报错退出的情况)

SELECT *

FROM

(

SELECT rownum num ,t.*

FROM TI_BI_CAMPN_USERORDER_TEMP t

WHERE oper_type = '0' OR oper_type = '2' OR

(oper_type = '1' AND end_date <= add_months(trunc(sysdate, 'mm'), 1))

ORDER BY oper_time ASC

) c

WHERE c.num <= : 1;

表记录数280M,返回其中符合条件并按oper_time排序的500条记录。

看到上面sql monitor显示的执行计划,可能有人会生出疑问:

返回了表的大部分记录,为什么不做全表扫描,而是使用了比较差的索引扫描?

答案是:

因为修改了索引相关的两个系统参数,把索引的COST大大的降低了,让优化器认为走索引总是比全表扫描要好:

optimizer_index_caching = 95(默认值0)

optimizer_index_cost_adj = 3(默认值100)

这个SQL如何优化呢?

根据SQL monitor显示的信息及表的实际记录数,我们可以通过创建oper_time字段上的索引来优化:

create index idx_name on TI_BI_CAMPN_USERORDER_TEMP(oper_time);

预计创建索引后,该SQL的执行时间应该在1~2秒左右

小结:

order by 与 rownum 搭配使用时,可以创建谓词字段与order by字段上的联合索引(本例不可,因为有or和不对称的谓词条件);或者在大部分数据都符合条件的情况下,创建order by字段上的索引(本例),避免大结果集的排序。

系统默认参数一般不建议修改(内存参数、bug除外),因为很多性能测试是在默认参数条件下完成。

其他情况:

如果这个SQL执行频率低,也可以选择不创建索引,使用并行加全表扫描来提高响应速度,使用下面的hint:

SELECT *

FROM

(

SELECT /*+ full(t) parallel(4) */rownum num ,t.*

FROM TI_BI_CAMPN_USERORDER_TEMP t

WHERE oper_type = '0' OR oper_type = '2' OR

(oper_type = '1' AND end_date <= add_months(trunc(sysdate, 'mm'), 1))

ORDER BY oper_time ASC

) c

WHERE c.num <= : 1;

如果索引那两个系统参数是默认值,其中的full hint是可以去掉的。

当前使用的并行度是4,具体的并行度可以根据实际需要适当增减。

注意:11g的并行写法已经不要求加表名或别名。10g中加表名或别名的写法繁琐而且容易遗漏,抛弃了吧!

各位网友如果有什么意见、建议、问题都可以与老虎刘沟通。

老虎刘的文章都是原创,欢迎大家转发。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
访问管理
访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档