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条件中有该索引列上的条件;
如果能实现按照索引扫描,性能有成千上万倍的提升也是非常可能的,这点在实践中得到了验证。
热门推荐
龙岩市第一医院医生登顶《英国医学杂志》:青年医师易熠发表重要个案报道
轻松备战马拉松:10个实用建议助力完赛
马拉松训练与比赛完全指南:四大技能助你突破
Nature最新研究:大豆异黄酮可改善脂肪肝,专家详解
“1%灵感+99%汗水”:爱迪生的发明人生与三大成就
人口负增长下的养老难题:挑战与应对
人口老龄化:挑战与应对
社交焦虑症
社交焦虑症
阿莫西林抗菌,布洛芬止痛:两类常用药的区别
滥用抗生素致耐药性激增,中国年均数万人因此死亡
感冒发烧吃什么菜好
鸡是“发物”还是补药?一次性讲清楚
冰箱除霜神器大揭秘:告别结霜烦恼
冬季冰箱除霜全攻略:让冰箱保持最佳状态
冰箱除霜大作战:速战速决!
LG冰箱除霜秘籍,你get了吗?
哈尔滨泼水成冰,小心被烫伤!
泼水成冰:科学原理与安全指南
哈尔滨泼水成冰,小心变泼水成伤!
泼水成冰挑战,-40℃才是真·极寒
国家力推匹克球运动,科学证实助益中老年身心健康
新疆旅游攻略:四季气候全解析
家庭版红烧肉,让你秒变厨神!
红烧肉这样做,连隔壁小孩都馋哭了!
五花肉搭配秘籍,红烧肉完美升级
冬季养生,六味地黄丸or金匮肾气丸?
关羽之死:历史的真相与传说的辨析
法家思想助秦孝公后代君王统一天下
2023年农村人均收入破2万,消费支出增9.3%