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条件中有该索引列上的条件;
如果能实现按照索引扫描,性能有成千上万倍的提升也是非常可能的,这点在实践中得到了验证。
热门推荐
私家车一般多少公里换一次轮胎?有何注意事项?一文说清楚
脑梗药物治疗方法有哪些
苹果相机摄像头安装教程-如何在iPhone上设置相机-苹果手机摄像头安装指南
如何表达爱情:利用这11种不用言语的方式,是最完美的感情表达
企业家IP的千人千面,从乔布斯、马斯克这里学到了什么?
Markdown格式列表分组指南
《哭泣杀神》:一部探讨人性与救赎的震撼动作影片
满天星夏天怎么养
如何控制自己易怒的情绪
智能充电桩充满电了会自动断电吗?
日本研究"量子恶魔引擎"?看似"永动机",违反热力学却有可能!
微信找群聊太难?4个实用技巧帮你快速定位所有群聊
江苏南京:老城焕新打开“人文经济”密钥
猪肉排的四种做法(不同口味、吃到饱,爱上猪肉排!)
国产电影母亲形象正在蜕变?
药物不良反应的类型与识别方法
关于沉降观测,这些您必须知道!
如何用照片记录一次难忘的旅行:技巧与建议
怎样克服自以为是毛病
揭秘:“浑家”一词的真正含义是什么?
CS2殒命大厦地图全攻略:2025最新报点指南
肚子抽筋是什么原因
于月仙经典作品回顾:从默默无闻到“谢大脚”
只能嚼不能咽 “三无”产品充斥 网红零食蜡瓶糖安全隐患大
满天星种子种植过程(从播种到开花)
青椒的营养价值与功效
四柱八字排盘中神煞红艳解析
八字十二长生解析:辛亥日主在婚姻中的影响
未雨绸缪,防患未撞:CNC加工中防止撞刀的关键策略
猪肉馅怎么调才又鲜又嫩?4点要记住!