我们进行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优化器认为过滤条件内没c1列,走索引比走FTS效率更低,所以,干脆就不考虑走索引这种计划,即使用hint也要忽略,这点感觉有点不尽人意。那么,我们想什么办法才能让优化器选择扫描idx1_t1的计划呢?我们只需要在where中加个c1列上的条件就可以了,例如:

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

这么修改后的计划如下:

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

1、排序列上存在索引;

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

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

SQL优化(SQL TUNING)可大幅提升性能的实战技巧之一——让计划沿着索引跑的更多相关文章

  1. Java 性能优化手册 — 提高 Java 代码性能的各种技巧

    转载: Java 性能优化手册 - 提高 Java 代码性能的各种技巧 Java 6,7,8 中的 String.intern - 字符串池 这篇文章将要讨论 Java 6 中是如何实现 String ...

  2. oracle 11g亿级复杂SQL优化一例(数量级性能提升)

    自从16年之后,因为工作原因,项目中就没有再使用oracle了,最近最近支持一个项目,又要开始负责这块事情了.最近在跑性能测试,配置全部调好之后,不少sql还存在性能低下的问题,主要涉及执行计划的不合 ...

  3. 面试题: 数据库 sql优化 sql练习题 有用 学生表,课程表,成绩表,教师表 练习

    什么是存储过程?有哪些优缺点? 什么是存储过程?有哪些优缺点? 存储过程就像我们编程语言中的函数一样,封装了我们的代码(PLSQL.T-SQL). 存储过程的优点: 能够将代码封装起来 保存在数据库之 ...

  4. SQL优化SQL tuning

    1. 索引不合适,走主键进行了key lookup查找   说明索引没有覆盖到where条件 或者  orderby 或者 group by的列

  5. sql 优化 -- sql中的自定函数

    Long run sql: MERGE INTO INTITMRTNPARAM D USING ( SELECT A.INRFILENM,A.INRSTAT,A.INRDEPCD,A.INRITMCD ...

  6. SQL优化 | sql执行过长的时间,如何优化?

    1.查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化) 2.涉及链表的查询,是否能进行分表查询,单表查询之后的结果进行字段整合 3. ...

  7. SQL 优化SQL查询

    摘至于:http://www.cnblogs.com/ATree/archive/2011/02/13/sql_optimize_1.html 1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据 ...

  8. SQL优化笔记一:索引和explain

    目录 为什么需要优化SQL SQL优化的重点 索引 索引的结构 索引的优缺点总结: 索引的分类 索引操作 B树 实战 问题 数据库方面,我会使用MySQL来讲解 为什么需要优化SQL 性能低,执行时间 ...

  9. php面试专题---Mysql索引原理及SQL优化

    php面试专题---Mysql索引原理及SQL优化 一.总结 一句话总结: 注意:只写精品 1.为表设置索引要付出代价 是什么? 存储空间:一是增加了数据库的存储空间 修改插入变动索引时间:二是在插入 ...

随机推荐

  1. Python Web学习笔记之Python多线程基础

    多线程理解 多线程是多个任务同时运行的一种方式.比如一个循环中,每个循环看做一个任务,我们希望第一次循环运行还没结束时,就可以开始第二次循环,用这种方式来节省时间. python中这种同时运行的目的是 ...

  2. 微信小程序开发环境

    微信小程序开发环境 不忘初心,方得始终.初心易得,始终难守 小程序开发环境 开发工具下载地址:https://developers.weixin.qq.com/miniprogram/dev/devt ...

  3. [省选模拟]Rhyme

    考的时候脑子各种短路,用个SAM瞎搞了半天没搞出来,最后中午火急火燎的打了个SPFA才混了点分. 其实这个可以把每个模式串长度为$K-1$的字符串看作一个状态,这个用字符串Hash实现,然后我们发现这 ...

  4. 多态时最好将基类的析构函数设为virtual、 C++中两个类相互包含引用问题 (转载)

    多态:http://blog.csdn.net/tmljs1988/article/details/8146521 C++中两个类相互包含引用问题:http://blog.csdn.net/leo11 ...

  5. updateByPrimaryKeySelective更新失败

    问题:使用Mybatis中Mapper内置方法updateByPrimaryKeySelective更新失败. 发现:控制台打印出来的sql语句发现where条件出现所有属性. 解决:映射的实体类没有 ...

  6. Thinking in React 观后感

    原文地址:Thinking in React 今天在翻阅 React 文档,看到一篇名为「Thinking in React」的文章觉得写的很好.文章介绍了如何使用 React 构建一个应用,并不是手 ...

  7. SQL Server @@参数一览表

    --返回 SQL Server 自上次启动以来尝试的连接数,无论连接是成功还是失败. SELECT @@CONNECTIONS AS CONNECTIONS --返回 SQL Server 自上次启动 ...

  8. SQL语句 查询同一个字符在某一个字符串中出现的次数

    select len(replace(字段名A,';','--'))-len(字段名A) from table表名

  9. 返回json格式数据乱码

    本文为博主原创,未经允许不得转载: 原本返回json格式数据的代码: @ResponseBody @RequestMapping(value = "getListByTime", ...

  10. 微信网页跳转页面常见bug处理

    微信网页跳转页面常见bug处理 1.不要直接用a链接直接跳转 2.url后加上时间戳 function gohome() { window.location.href = "../home/ ...