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条件中有该索引列上的条件;
如果能实现按照索引扫描,性能有成千上万倍的提升也是非常可能的,这点在实践中得到了验证。
热门推荐
双通道内存有什么优点和缺点
广州中考科目卷面分值引关注,近年来经历了哪些变化?
“智造”赋能 民营企业加快提升含“新”量
周光召先生的科学贡献和影响
怎么替换EXCEl里面的数据源
居间合同如何交税?全面解析税务处理与法律风险防范
如果在Mac设置过程中键盘或鼠标无法连接
宏观经济学中三种均衡模型
“国家队”护航科学减重,解码北京大学人民医院“体重管理”门诊
陈伟教授:数字化赋能体重管理的实践与应用 | COC 2024
惠州楼市“银十”回温:成交量攀升 未来展望如何?
18家券商喜提A类 无D类券商 信披评价结果会带来哪些影响?
胆囊切除术后胆区疼痛的原因及应对方法
苏州留园:一座集自然、建筑与文化于一体的古典园林
史上最经典最短的10首古诗,不超过40个字,却依然流传千古
偿债能力的指标有哪些
常用的财务指标计算公式、分析和解释有哪些
入夏预防食物中毒指南
猫眼效果的和田玉或翡翠玉?深入解析二者的区别与鉴别方法
棉服和羽绒服怎么清洗保养 选购技巧介绍
怎样才能更好地利用上海的五险一金
意大利科学家已经证实,吃披萨令人快乐
如何选择合适的加油站?加油站的选择和使用有哪些关键因素?
把家里55寸电视换成85寸,体验了半年,这些心里话不吐不快
移动加权平均法:概念、应用与优势详解
黄瓜适合什么土壤种植?黄瓜的土壤选择和种植方法是什么?
HART协议原理及其应用
圣经中真理审判讲章的法律意蕴与现实启示
各部门之间如何协作融合
购房合同资金来源的法律问题探讨