项目中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
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 估计当前操作的时间。