通过对一些查询方式和细节的调整,有时能大大提高查询的效率,本次文章整理自《SQL进阶教程》,这本书为大家提供了很多简单易行的查询优化方法,即使你不具备数据库理论知识,也能够很容易的掌握到。
笔记纲要:
1、使用高效的查询方式
2、避免排序
3、善用索引
4、减少中间表
1、使用高效的查询方式
①在子查询中,用EXISTS代替IN
exists只要查到一行数据满足条件就会终止查询。不用像使用in时扫描全表,大大提高了查询效率。
②使用表连接代替IN
特别是连接字段设置了索引时,采用表连接是比较有效的。
2、避免排序
会进行排序的代表性运算有:
- GROUP BY
- ORDER BY
- 聚合函数(SUM、COUNT、AVG、MAX、MIN)
- DISTINCT
- 集合运算符(UNION、INTERSECT、EXCEPT)
- 窗口函数(RANK、ROW_NUMBER等)
①用UNION ALL代替UNION
union all 不会进行排序,但由于其不具备去重功能,因此需要添加别的限制条件。
②用EXISTS代替DISTINCT
③在极值函数中使用索引
如MAX(id)中,将id添加索引,在寻找最大值时能够提高查询效率。
④当需要运用GROUP BY分组时,能用WHERE别用HAVING
因为where子句用在group by 之前,可提前对查询的内容进行筛选,减少了后续group by的工作量;
having需要用在group by之后,且having子句是针对聚合后生成的视图进行筛选的,很多时候聚合后的视图都没有继承原表的索引结构。
⑤在GROUP BY子句和ORDER BY子句中使用索引
这两个子句都会进行排序,索引能够有助于提升排序效率。
3、善用索引
很多时候,由于对索引使用时的不当,导致不能发挥索引对于查询的优化能力。
①不要在索引字段上进行运算
select * from student where age-10>10;
在这种情况下,并没有真正的用到age列的索引,正确的方式是:
select * from student where age>20;
②不要使用IS NULL
通常,索引字段是不存在NULL的,所以指定IS NULL会使得索引无法使用。
③慎用否定形式
下面这几种否定形式会对全表进行扫描,使索引失效:
- <>
- !=
- NOT IN
④慎用OR
若在col_1和col_2分别建立了不同的索引,或者建立了(col_1,col_2)这样的联合索引时,如果使用OR连接条件,要么用不到索引,要么用到了但是比AND效率差很多。
⑤使用联合索引时,保证列的顺序正确
如建立了(col_1,col_2)的联合索引,索引中的第一列必须写在条件的开头
select * from student where col_1=10 and col_2=20;
而不能写为
select * from student where col_2=20 and col_1=10;
⑥使用LIKE时,只能进行前方一致的匹配
即
select name from student where name like 'a%';
4、减少中间表
频繁使用中间表会带来两个问题:
- 一是展开数据需要耗费内存资源;
- 二是原始表中的索引不容易使用到(特别是聚合时)
①灵活使用HAVING子句
对聚合结果指定筛选条件是不需要专门生成中间表,使用HAVING子句就可以。
②需要对多个字段使用IN时,将它们汇总到一处
select * from student s1
where id || state || city
in (select id || state || city from student s2);
③先进行连接在进行聚合
④合理的使用视图
当视图中包含以下运算时,SQL会非常低效:
- 聚合函数(SUM、COUNT、AVG、MAX、MIN)
- 集合运算符(UNION、INTERSECT、EXCEPT)