rownum优化 sqlserver_SQL TUNING优化时可大幅提升性能的实战技巧之一――让计划沿着索引跑...

我们进行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条记录,计划以下:

c7f1448386aa5688696a5fe32c1c7013.png

如果我们这么写,语义是1样的,但会省去了大量的读取和排序代价:

select /*+ index(t1,idx1_t1)*/* from t1 where rownum<6;

该SQL的履行计划以下:

d773625d0d12bdfea9426d6e25e75828.png

大家可以看到,该SQL并没依照hint唆使,顺序扫描idx1_t1索引,这是为何呢?个人猜想,多是Oracle优化器认为过滤条件内没c1列,走索引比走FTS效力更低,所以,干脆就不斟酌走索引这类计划,即便用hint也要疏忽,这点感觉有点不尽人意。那末,我们想甚么办法才能让优化器选择扫描idx1_t1的计划呢?我们只需要在where中加个c1列上的条件就能够了,例如:

select /*+ index(t1,idx1_t1)*/* from t1 where rownum<6 and c1<>⑴;

这么修改后的计划以下:

0f57ac2bb08e3e5a4f7ff3d19ea9a58d.png

因而可知,我们优化类似场景时,只需满足两点:

1、排序列上存在索引;

2、where条件中有该索引列上的条件;

如果能实现依照索引扫描,性能有不计其数倍的提升也是非常可能的,这点在实践中得到了验证。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值