SQL优化实战:让查询沿着索引跑的技巧
创作时间:
作者:
@小白创作中心
SQL优化实战:让查询沿着索引跑的技巧
引用
CSDN
1.
https://blog.csdn.net/weixin_40345397/article/details/140650885
在进行SQL优化时,我们经常会遇到需要对大量数据集进行排序,然后从排序后的集合中取前部分结果的需求。在这种情况下,如果按照常规思路去写SQL,系统会先读取过滤获得所有集合,然后进行排序,再从排序结果中取出极少量结果。这个过程中,大量数据的扫描读取、过滤、排序会消耗掉大量的系统资源,导致SQL性能存在很大问题。实践中,几分钟乃至几个小时不出结果的情况很常见。
为了优化这种场景的SQL,我们经常会让查询顺序扫描建在排序列上的索引,以避开大量的数据读取和排序。但实践中发现,当索引列不在条件中出现时,Oracle不会产生扫描索引的计划,即使使用hint也不能让查询沿着目的索引扫描。
例如:
create table t1(c1 int,c2 char(10));
create index idx1_t1 on t1(c1);
select * from (
select * from t1 order by c1)
where rownum<6;
很明显,这种写法会导致先读取表,再进行排序,然后取前5条记录。其执行计划如下:
如果我们这么写,语义是一样的,但会省去了大量的读取和排序代价:
select /*+ index(t1,idx1_t1)*/* from t1 where rownum<6;
但是,该SQL并没有按照hint指示,顺序扫描idx1_t1索引。个人猜测,可能是Oracle优化器认为过滤条件内没c1列,走索引比走FTS效率更低,所以,干脆就不考虑走索引这种计划,即使使用hint也要忽略,这点感觉有点不尽人意。
那么,我们想什么办法才能让优化器选择扫描idx1_t1的计划呢?我们只需要在where中加个c1列上的条件就可以了,例如:
select /*+ index(t1,idx1_t1)*/* from t1 where rownum<6 and c1<>-1;
修改后的执行计划如下:
由此可见,我们优化类似场景时,只需满足两点:
- 排序列上存在索引;
- where条件中有该索引列上的条件;
如果能实现按照索引扫描,性能有成千上万倍的提升也是非常可能的,这点在实践中得到了验证。
热门推荐
火山熔岩分类及其显著特征
苏轼《题金山寺》:一首正着读天亮、倒着读天黑的回文诗
亲子鉴定:揭秘遗传病的秘密
九江文化瑰宝:琵琶亭与浔阳楼
医保卡内的个人账户资金,符合以下情形,可以申请提现
致癌物超标!这几款降压药已经被召回,赶紧看看你家有没有?
冬游九江:庐山雪景与鄱阳湖候鸟的双重盛宴
扬州大学中医科教你甲流恢复秘籍
亲子鉴定报告成离婚案关键证据,司法程序与法律效力全解析
甲流高发季,这样吃加速康复!
哈尔滨中央大街:改造升级后的冰雪新玩法
甲流恢复期饮食调理指南:五种体质辨证施治方案
中央大街变身全国高品位步行街,你期待吗?
20个驾驶口诀,牢记于心,即可避免90%的交通事故
亲子鉴定报告里的“黑话”,你知道多少?
缤纷赏秋向九江:秋季特色活动推荐
每天喝一杯速溶咖啡到底好不好?告诉你健康饮用方法
冬季西藏5日深度旅行攻略
各种蔬菜温度多少就可以种植,五大类几十种蔬菜,春天正好能用上
设施蔬菜春季如何管理,根据棚室温度变化做好低温防冻措施
庐山鄱阳湖自驾游,最美季节揭秘
长三角自驾游路线 江西安徽浙江江苏自驾游高清地图 长三角环线路线图
little和small有什么区别
出国旅行必备!机场常用英语,带你走遍天下都不怕~
南宁青秀山植物园打卡攻略:最佳拍摄时间与机位详解
青秀山特色植物打卡攻略:千年苏铁、百亩兰园等你探秘
青秀山千年苏铁王的重生之路
三县市高速直达! 宜攀高速小黑箐互通至和爱互通段正式通车
真巴适,宜宾至攀枝花高速建设进度喜人,明年有望全线开通
甲流恢复期,这样吃才能快速回血