--SQL优化
--优化方向
设计方面:分区表、拉链表、临时表、表模型、表结构
开发方面:索引、SQL基础优化、语言标准化、重复代码量、WITH...AS
硬件方面:CPU、内存
-------------------------------------------------------------------------------
--SQL基础优化
--FROM子句后面表名的顺序
ORACLE解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表将被优先处理。
在FROM子句中包含多个表的情况下,必须选择记录条数最小的表作为基础表
--WHERE子句后面的过滤条件
ORACLE采用从后往前的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前,
那些可以过滤最大数量记录的条件必须写在WHERE子句的末尾。
在进行多表关联时,多用WHERE语句把单个表的结果集最小化,多用聚合函数汇总结果集后在与其他表做关联,
以使得结果集数据量最小化。
--减少程序代码的重复次数
减少对表的查询,如在含有子查询的SQL语句中,要特别注意减少对表的查询,多用WITH...AS语句
--用EXISTS(NOT EXISTS)替代IN(NOT IN)
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下使用EXISTS
或NOT EXISTS通常将提高查询的效率,使用EXISTS而不用IN因为EXISTS只检查行的存在,而IN检查
实际的值
SELECT * FROM EMP WHERE DEPTNO IN(
SELECT DEPTNO FROM DEPT WHERE LOC='NEW YORK'); --效率低
SELECT * FROM EMP E WHERE EXISTS(SELECT 1 FROM DEPT D
WHERE E.DEPTNO=D.DEPTNO AND D.LOC='NEW YORK'); --效率高
--尽量不用少用DISTINCT
当提交一个包含一对多表信息的查询时,避免在SELECT子句中使用DISTINC,可以考虑用EXISTS替换
--用>=代替>
前者DBMS将直接跳到第一个DEPT等于4的记录,而后者将首先定位到DEPTNO=3的记录并且向前扫描到
第一个大于3的记录。
--LIKE操作符用INSTR函数代替
遇到使用LIKE过滤的语句,可以尝试用INSTR代替,处理效率将显著提高
--优化GROUP BY
提高GROUP BY语句的效率,可以通过WHERE语句将不需要的记录在GROUP BY之前过滤掉(WHERE
是用于过滤行的,而HAVING是用来过滤组的,因为行被分组后,HAVING才能过滤组,所以尽量使用
WHERE过滤)
--SELECT子句后使用具体的列名代替使用*
任何地方不要使用SELECT * FROM T,用具体的字段来替代*,不要返回用不到的任何字段。
--索引的合理使用方面
1)避免在索引列上使用计算,WHERE子句中,如果索引列是函数的一部分,优化器将不再使用索引而使用
全表扫描。
2)避免在索引列上使用NOT、<>、!=等否定符号,因为这会导致索引失效。
3)避免改变索引列的数据类型,因为当索引列发生类型转换时,可能导致索引失效。
4)避免在WHERE子句对字段进行NULL值判断,因为这将导致索引失效。
5)避免在WHERE子句中使用OR来连接条件,因为这将导致索引失效。
6)IN和NOT IN也要慎用,,因为这将可能导致索引失效。
7)在使用复合索引时,必须使用到索引列中的第一个字段作为条件是才能保证系统使用该复合索引。并且应
尽可能的让字段顺序与索引的顺序相一致。