SQLTUNING优化时可大幅提升性能的实战技巧之一

来源:IT165收集  发布日期:2015-04-30 01:04:27

我们进行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的执行计划如下:


大家可以看到,该SQL并没按照hint指示,顺序扫描idx1_t1索引,这是为什么呢?个人猜测,可能是Oracle优化器认通ky"http://www.it165.net/qq/" target="_blank" class="keylink">qq5/cLLzPW8/sTaw7tjMcHQo6zX38v30v2xyNffRlRT0KfCyrj8tc2jrMv50tSjrLjJtOC+zbK7v7zCx9ffy/fS/dXi1ta8xruuo6y8tMq508NoaW500rLSqrr2wtSjrNXiteO40L7109C147K7vqHIy9LioaPEx8O0o6zO0sPHz+vKssO0sOy3qLLFxNzIw9PFu6/G99Gh1PHJqMPoaWR4MV90MbXEvMa7rsTYo7/O0sPH1rvQ6NKq1Np3aGVyZdbQvNO49mMxwdDJz7XEzPW8/r7Nv8nS1MHLo6zA/cjno7o8L3A+CjxwPnNlbGVjdCAvKiYjNDM7IGluZGV4KHQxLGlkeDFfdDEpKi8qIGZyb20gdDEgd2hlcmUgcm93bnVtJmx0OzYgYW5kIGMxJmx0OyZndDstMTs8YnI+CjwvcD4KPHA+1eLDtNDeuMS687XEvMa7rsjnz8KjujwvcD4KPHA+PGltZyBzcmM9"http://www.it165.net/uploadfile/files/2015/0429/20150429192323485.png" alt="">

由此可见,我们优化类似场景时,只需满足两点:

1、排序列上存在索引;

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

如果能实现按照索引扫描,性能有成千上万倍的提升也是非常可能的,这点在实践中得到了验证。

Tag标签: 实战   性能   技巧  
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规