mysql的优化器位于服务层,是查询高效的一个重要保证,但是它到底干了什么?你知道吗?
![fcfd1771df05007deb3af66050448ffb.png](https://i-blog.csdnimg.cn/blog_migrate/6124a5cccdc9c483930e70d00a915a3a.jpeg)
将外连接转化成内连接
并不是所有的OUTER JOIN语句都必须以外连接的方式执行。有诸多因素,例如WHERE
条件、库表结构都可能会让外连接等价于一个内连接。MySQL能够识别这点并重写
査询,让其可以调整关联順序。
使用等价变换规则
MySQL可以使用一些等价变换来简化并规范表达式。它可以合并和减少一些比较,
还可以移除一些恒成立和一些恒不成立的判断。例如,(5=5 AND a>5)将被改写为
a>5。类似的,如果有(a5 AND b=c AND a=5。
这些规則对于我们编写条件语句很有用。
优化 C0UNT()、MIN()和 MAX()
索引和列是否可为空通常可以帮助MySQL优化这类表达式。例如,要找到某一列
的最小值,只需要査询对应B-Tree索引最左端的记录,MySQL可以直接获取索引
的第一行记录。在优化器生成执行计划的时候就可以利用这一点,在B-Tree索引中,
优化器会将这个表达式作为一个常数对待a类似的,如果要査找一个最大值,也只
铕读取B-Tree索 引 的 最 后 一 条 记 录 如 果MySQL使用了这种类型的优化,那么在
EXPLAIN中就可以看到“Select tables optimized away”。从字面意思可以看出,它表
示优化器已经从执行计划中移除了该表,并以一个常数取而代之。
类似的,没有任何WHERE条件的COUNT(*)査询通常也可以使用存储引擎提供的一些
优化(例如,MylSAM维护了一个变量来存放数据表的行数)。
及盖索引扫描
当索引中的列包含所有査询中需要使用的列的时候,MySQL就可以使用索引返回需
要的数据,而无须査询对应的数据行。
子查询优化
MySQL在某些情况下可以将子査询转换一种效率更髙的形式,从而减少多个査询多
次对数据进行访问。
提前终止查询
在发现已经满足査询箱求的时候,MySQL总是能够立刻终止査询。一个典型的例子
就是当使用了 LIMFT子句的时候。除此之外,MySQL还有几类情况也会提前终止査
询,例如发现了一个不成立的条件,这时MySQL可以立刻返回一个空结果。
列表IN()的比较
在很多数据库系统中,IN()完全等同于多个OR条件的子句,因为这两者是完全等
价的。在MySQL中这点是不成立的,MySQL将IN(>列表中的数据先进行排序,
然后通过二分査找的方式来确定列表中的值是否满足条件,这是一个〇(log n)复杂
度的操作,等价地转换成OR査询的复杂度为〇(n),对于IN()列表中有大量取值的
时候,MySQL的处理速度将会更快。