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条件中有该索引列上的条件;
如果能实现按照索引扫描,性能有成千上万倍的提升也是非常可能的,这点在实践中得到了验证。
热门推荐
忆乡愁 品年味|昌邑大饽饽掰开能有60多层,热吃绵软凉吃如栗
人事综合评价系统怎么填写
特级初榨橄榄油炒菜安全指南:高温烹饪会影响其营养价值吗?
欧丽薇兰特级初榨橄榄油:炒菜更健康的选择
寒假社会实践:提升你的职场竞争力!
让寒假更有意义:大学生社会实践指南
兰新高铁飞驰 助力西部发展(大数据观察)
如何用STAR(情境、任务、行动、结果)方法来结构化回答问题?
儿童骨折后吃什么营养品补品好呢
毅玲爸爸:用流量助农的公益之路
躺刷手机致视力受损,专家提醒:这些习惯要不得
珍视明教你告别手机眼疲劳
侧躺刷手机伤眼又伤身!
睡前刷手机的危害,你真的了解吗?
龙兴古镇:重庆历史文化名镇的前世今生
长期低烧是什么原因引起的
引起低热的原因有哪些
人体低热是什么症状
家庭虐待:如何保护家人?
上春山,膝盖保护不可忘:专家教你3招
研究揭示:咖啡竟是膝关节炎的“帮凶”?这些饮食习惯或可降低患病风险
膝关节保健操:保护膝盖的八个小动作
清朝的八旗满城是怎么回事?其实都是军事堡垒
流浪猫为何如此孤僻?心理学揭秘
朱天心《猎人们》:流浪猫的社会化秘密
流浪猫的性格密码:从独立到信赖
冬日烟台:雪景海浴与温泉的完美邂逅
烟台最美100公里海岸线自驾攻略:从金沙滩到养马岛
烟台山老建筑里的浪漫往事:林徽因与胡蝶的烟台时光
蓬莱仙境:八仙过海打卡胜地