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条件中有该索引列上的条件;
如果能实现按照索引扫描,性能有成千上万倍的提升也是非常可能的,这点在实践中得到了验证。
热门推荐
地西泮鼻喷雾剂:癫痫急救的新选择
美国媒体揭露:脱毛膏核心成分或有致癌风险
财务票据是什么?一文详解票据类型、法律效力与应用场景
杭州36家企业跻身“2024中国民营企业500强”,连续22年蝉联全国城市第一
自动挡汽车下坡怎么挂挡?老司机:挂D档踩刹车很危险
如何快速计算光伏发电量?光伏发电量计算公式?
医生解读:眼角发白的五大原因及应对方法
信号分析的四大领域:时域、时延域、频域和幅值域
南宋祭祀礼仪:从战火中重塑政权正统性与合法性
多重宇宙与平行宇宙:我们的决定如何创造新的现实?
机构投资者在黄金定价中的作用
错杀股的识别方法有哪些?这些方法在投资实践中的效果如何?
怎么考取人社部电工证?
菠菜炒鸡蛋的营养价值
王者荣耀韩信怎么说话的 王者荣耀韩信台词解析
佛山三山岛旅游攻略:自然与文化的完美融合
中国这些绝美的火车站,你去过几个?
肝癌患者饮食禁忌:这3类食物千万别碰
视频剪辑的就业方向与就业前景怎么样?
制定员工工资薪酬方案时需要考虑哪些因素?
煎牛排的正确方法与技巧
战胜脚臭:男性的有效对策
生地能中和四物汤中药物的温热之性吗
控制情绪的三个技巧
IPv6有哪些显著优势和好处?
什么是IPv6?
当代人的旅行观:与其走马观花,不如慢下来
【春节Yi对Yi】 扬州“富春茶点制作技艺”:一壶水煮三省茶 饮与食皆世界级
散热需求变化下的VC均热板产品发展
票据支付方式有哪些?常见的有10种,早知早受益