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条件中有该索引列上的条件;
如果能实现按照索引扫描,性能有成千上万倍的提升也是非常可能的,这点在实践中得到了验证。
热门推荐
江苏暑期打卡胜地:拙政园、夫子庙、鼋头渚
北京至桂林北海:11天深度游完全攻略
经营分析的年度报告模版,赶紧收藏!
军队中的吹号声叫什么名字?
本命年过生日的讲究
王宝强:已经踩好点了
广州增城周末游:森林海温泉度假酒店+白水寨打卡攻略
探访增城古村落:从旧高埔到吾乡石屋
冬日打卡白水寨,感受岭南山水之美
广州东部的“翡翠绿洲”:走进增城大封门林场
新生儿听力发育全攻略:爸妈必看!
耳朵畸形背后的遗传密码:从基因突变到治疗新希望
杯状耳畸形治疗迎来新突破:无创矫正技术让宝宝重获完美耳型
人工智能ETF份额波动:市场影响与投资者机遇分析
涠洲岛:北海最美自然景观打卡地
春节非遗之旅:北海贝雕与南珠探秘
《第五人格》:如何完美扮演守夜人?
《权力的游戏》中的守夜人:从长城守护者到异鬼克星
《第五人格》官方推荐:守夜人角色深度解析
广东惠州南昆山:秋日里的自然画卷
肝脏“硬不硬”?弹性成像告诉你~
海拔高!收视率更高!春晚拉萨分会场惊艳了你我!
苏州夏日避暑胜地大揭秘!
秋冬打卡江苏最美湿地:赤山湖与太湖
暑假江苏必打卡:夫子庙与中山陵
有望实现榴莲自由?金枕榴莲在云南试种成功,甜度超过34%
ETF与股票大对比:这些关键差异你了解吗?
ETF基金如何跟踪指数
雨天打卡桂林:芦笛岩、刘三姐大观园、石涛书画院
夜蛾正道:一位咒术师的自我修养