mysql体系结构参考:https://www.jianshu.com/p/765ec1187f8e
sql执行顺序参考: https://blog.csdn.net/qq_34693104/article/details/81258122
sql优化参考:https://shensy.iteye.com/blog/1887786
SQL优化的基本思想:
- 最小化结果集数据量。
Sql所需处理的资源总量/Sql单位时间所能处理的资源量=Sql执行时间
所以为减少Sql执行时间:
1)可以增大Sql单位时间所能处理的资源量。
2)可以减少Sql所需处理的资源总量。
前者一般需要增加物理资源,所以常见的方法是后者,减少执行sql所处理的行数。 - 减少全表扫描。
减少全表扫描,主要手段就是建立索引,索引就好比一本书的目录,当你需要查询某篇文章时,不需要从头到尾把书的每页都查一遍,直接看目录就能找到了。
在没有建索引的情况下,从数据库查找某一条数据,就必须进行全表扫描,即对所有数据进行一次遍历。但即使在建立了索引的情况下,也会出现类似情况发生,因此要尽量避免全表扫描。
具体优化手段
-
尽量把使用索引的列放在where条件首列。
-
不要过多地使用通配符*,而是使用查询列。
-
避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描。考虑将null的列设置默认值0。
-
尽量避免在where子句中使用!=操作符,否则将引擎放弃使用索引而进行全表扫描。
not运算无法使用索引,可以改成其他能够使用索引的操作。如下:
-
where与having
select … from … on … where … group by … having … order by … limit …,以上是sql语句的语法结构,其中on、where和having是有过滤行为的,过滤行为越能提前完成就越可以减少传递给下一个阶段的数据量,因此如果在having中的过滤行为能够在where中完成,则应该优先考虑where来实现。 -
避免在where子句中使用or来连接条件,否则将导致引擎放弃使用索引而进行全表扫描。
-
in和not in也要慎用,IN会使系统无法使用索引,而只能直接搜索表中的数据。在索引列上,可以使用union替换or操作
-
尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。
SELECT * FROM table1 WHERE col1 LIKE ‘%L%’
改为:
SELECT * FROM table1 WHERE col1 LIKE ‘L%’ -
尽量避免在 where 子句中对字段进行表达式操作,不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算
SELECT * FROM table1 WHERE col1/2=100 -
尽量把使用的索引放在选择的首列。