最近遇到一个专门进行SQL技术优化的项目,对很多既有的老存储过程进行调优(现在已经不再新增任何存储过程),因此系统的对SQL语句编写进行一次科学的学习变得很有必要。这儿将基于黄德承大神的Oracle SQL语句优化一书,选取其中比较实用和通用的部分进行介绍。
-
任何SQL语句,只要在where子句中实用了is null或is not null,那么Oracle优化器不会使用索引。
-
任何where子句的条件的左侧不能出现函数,否则不走索引,比如WHERE YEAR(createtime) = '2016',可以用createtime>='2016-01-01'
-
在使用通配符%的like语句中,可以通过like 'c%'使用索引
-
order by语句,任何在order by语句的非索引项或者有计算表达式都将降低查询速度。
-
NOT和<>,会造成不走索引,应该选择使用where price<200 or price > 100。
-
IN和EXISTS,IN操作符的子查询都可以使用EXISTS代替,效率会高很多,where column in/exists (select 'X' from … where …),需要好好考虑。
Tip:
参数化SQL,like @count, '%'+ count +'%'
-
选择最优效率的表名顺序(Oracle解析器按照从右到左的顺序处理FROM子句中的表名),比如select count(*) from tab1 inner join tab2,这是优先检索表2,并将表2的数据与表1的合并。在SQL SERVER中,查看执行计划,发现并没有区别
-
减少查询的次数(包括对表查询),将多个分离的查询合并
-
能够在WHERE字句中使用的条件,尽量避免放在HAVING字句中
-
用EXISTS替代IN,用表连接替代EXISTS
-
用EXISTS替代DISTINCT,因为RDBMS会在子查询条件满足后立即返回结果
-
用索引来提高效率,定期的重构索引是有必要的
-
避免在索引列上计算
-
用>=代替>
-
注意隐式转换
-
UNION-ALL替换UNION
-
在严格遵守条件的情况下(所有的列必须包含在相同的索引中并保持在索引中的排列顺序,所有的列必须定义为非空),ORDER BY子句也是可以走索引的。