一、SQL优化的必要性
程序员开发项目的初期,由于数据量少的原因,对于查询SQL以及一些视图的编写没有过多注意,此时也体会不到SQL语句的性能差异。但是在项目上线后,随着数据的增加,SQL的执行效率对于程序运行的效率影响逐渐增大,导致系统的响应时间越来越慢,影响用户的操作体验,因此SQL的优化非常必要。
二、SQL优化
1.尽量避免select *的存在,使用具体的列,避免查询出不需要的、额外的数据;这些额外的数据在网络上进行传输,势必会造成性能延迟。
2.尽量避免一次性返回大量数据,建议分页返回。
3.尽量避免全表扫描,改为索引扫描。
1)建立适当的索引,索引就相当于字典的目录,按照索引查找就可以直接定位具体的页数,大大增加了查找的效率。建议对where以及order by涉及的列上建立索引(PS:索引需要额外的空间存放索引,并且每次insert、update以及delete都会对索引进行更新,会增加4-5次的磁盘IO,所以给一些不必要使用的字段增加索引,反而会降低系统的性能,因此一个表中的索引数量最好不要超过6个)。
2)尽量避免在where子句中对字段进行null值判断,这会导致全表扫描。在数据列创建时可以考虑添加一个默认值。
3)尽量避免在where子句中使用!=或者<>操作符,这会导致全表扫描。建议允许的情况下使用范围查询,如select col1 from A where col2<> 10 改为 select col1 from A where col2<10(假设10为最大值) 。
4)尽量避免在where子句中用or来连接,这可能会导致全表扫描。建议使用union all,例如select col1 from A where col2 = 1 or col2 = 10 改为 select col1 from A where col2 = 1 union all select col1 from A where col2 = 10。(PS:如果or两端的列都有建立索引的话,则会进行索引扫描)。
5)尽量避免左右模糊查询,这会导致全表扫描。建议使用右侧模糊查询,这个是可以通过索引查找的。例如将like %abc%改为like abc% 。
6)尽量不要执行算数运算后的比较,如函数、算数运算或者其他的表达式运算会导致全表扫描。建议将运算后的结果保存到数据表中,例如select col1 from A where col2 = col3/col4中,将col3/col4的结果另外保存在一个列中。
4.尽量使用数字型字段。如果只含数值信息的字段尽量不要涉及为字符型,这会降低查询和连接的性能,并且会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中的每一个字符,而对于数字型只需要比较一次就够了。
5.慎用in和not in,建议使用exist和not exist进行替代,如果是连续的数值,能够用between的就不要使用in了,例如 select col1 from A where col2 in(select col2 from B)改为 select col1 from A where exist(select 1 from B where col2 = A.col2); select col1 from A where col2 in(1,2,3)改为select col1 from A where col2 between 1 and 3。
6.慎用distinct、union、minus、intersect、order by等关键字。因为带有这些关键字的sql语句会启动SQL引擎执行,耗费资源的排序功能。distinct需要一次排序操作,而其他的至少需要执行两次排序。