图解如何提高SQL查询的效率

项目中SQL优化面试必考必用的一项技能,读者也在学习
对查询进行优化,要尽量避免全表扫描,首先应考虑在进行条件判断的字段上创建索引

尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。

1、避免 * 全表扫描

SELECT  *
  FROM   SCOTT.emp
    WHERE  job  IS  NULL;

2、避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。

 SELECT  *
  FROM   SCOTT.emp
    WHERE  job   <> 'SALESMAN';

3、避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描,而是使用union all实现

SELECT  *
  FROM   SCOTT.emp
    WHERE  job  = 'SALESMAN'  OR  sal>1000;

使用UNION ALL 来代替

SELECT  *
  FROM   SCOTT.emp
    WHERE  job  = 'SALESMAN'   UNION  ALL
    SELECT  *
  FROM   SCOTT.emp
    WHERE   sal>1000; 

4、避免not in ,否则会导致全表扫描,使用 NOT EXISTS 实现

SELECT  *
  FROM SCOTT.emp
    WHERE   empno  NOT  IN(7788);

使用NOT EXISTS代替

SELECT  *
  FROM SCOTT.emp  e1
    WHERE  NOT  EXISTS(
        SELECT *
          FROM  SCOTT.emp
            WHERE  e1.empno=7788
    );

5、模糊查询避免使用“%”也将导致全表扫描(MYSQL)
这种情况只有在mysql的时候会失效
在这里插入图片描述

 SELECT  *
  FROM SCOTT.emp 
    WHERE  job  LIKE  '%C%';

mysql索引失效解决
将用户可能输入的关键字使用下拉列表列出来,在数据库中使用全名称查询

SELECT  *  FROM emp  WHERE  job  LIKE  '关键字'

6、避免在 where 子句中对字段进行表达式计算操作,这将导致引擎放弃使用索引而进行全表扫描

SELECT  *
  FROM SCOTT.emp 
    WHERE   sal/2=1000;

在这里插入图片描述
解决方法

 SELECT  *
  FROM SCOTT.emp 
    WHERE   sal=2*1000;

在这里插入图片描述

7、使用索引字段作为条件时,如果该索引是复合索引。那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引(最左原则),否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。所谓的复合索引就是创建一个索引的时候作用在多个字段上。

  • 查询(不使用第一个字段)使用的是全表扫面模式。
 SELECT  *
  FROM  SCOTT.emp
    WHERE  sal>1000;

在这里插入图片描述

  • 查询(使用第一个字段,字段顺序与索引顺序一致)
 SELECT  *
  FROM  SCOTT.emp
    WHERE   job='SALEMAN';

在这里插入图片描述
使用复合索引的时候如果要其中一个字段,必须使用第一个字段(在创建索引时候的字段顺序)索引才会生效,这叫做索引的最左原则。

8、避免使用OR连接查询会导致索引失效,使用UNION ALL

  • 在OR连接中使用复合索引,索引失效
SELECT  *
  FROM  SCOTT.emp
    WHERE    sal>1000   OR  job='SALESMAN';

在这里插入图片描述

  • 使用UNION ALL解决
SELECT  *
  FROM  SCOTT.emp
    WHERE    sal>1000  UNION  ALL
SELECT  *
  FROM SCOTT.Emp
    WHERE  
     job='SALESMAN';

在这里插入图片描述
Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。

对于多张大数据量(这里几百条就算大了)的表JOIN,可以考虑使用程序去实现,不要做连接查询,就是尽量避开多表查询。

索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。

尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

SQLPLUS工具分析
一般按缩进长度来判断,缩进最大的最先执行,如果有2行缩进一样,那么就先执行上面的

ID: 一个序号,但不是执行的先后顺序。执行的先后根据缩进来判断。
Operation: 当前操作的内容。
Rows: 当前操作的Cardinality,Oracle估计当前操作的返回结果集。
Cost(CPU):Oracle 计算出来的一个数值(代价),用于说明SQL执行的代价。
Time:Oracle 估计当前操作的时间。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章