当你提交一个查询的时候MySQL会分析它看是否可以做一些优化使处理该查询的速度更快这一部分将介绍查询优化器是如何工作的如果你想知道MySQL采用的优化手段可以查看MySQL参考手册
当然MySQL查询优化器也利用了索引但是它也使用了其它一些信息例如如果你提交如下所示的查询那么无论数据表有多大MySQL执行它的速度都会非常快
SELECT * FROM tbl_name WHERE ;
在这个例子中MySQL查看WHERE子句认识到没有符合查询条件的数据行因此根本就不考虑搜索数据表你可以通过提供一个EXPLAIN语句看到这种情况这个语句让MySQL显示自己执行的但实际上没有真正地执行的SELECT查询的一些信息如果要使用EXPLAIN只需要在EXPLAIN单词放在SELECT语句的前面
mysql> EXPLAIN SELECT * FROM tbl_name WHERE \G
***************************
row ***************************
id:
select_type: SIMPLE
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: Impossible WHERE
通常情况下EXPLAIN返回的信息比上面的信息要多一些还包括用于扫描数据表的索引使用的联结类型每张数据表中估计需要检查的数据行数量等非空(NULL)信息
优化器是如何工作的
MySQL查询优化器有几个目标但是其中最主要的目标是尽可能地使用索引并且使用最严格的索引来消除尽可能多的数据行你的最终目标是提交SELECT语句查找数据行而不是排除数据行优化器试图排除数据行的原因在于它排除数据行的速度越快那么找到与条件匹配的数据行也就越快如果能够首先进行最严格的测试查询就可以执行地更快假设你的查询检验了两个数据列每个列上都有索引
SELECT col FROM mytable
WHERE col = some value AND col = some other value;
假设col上的测试匹配了个数据行col上的测试匹配了个数据行而同时进行的测试只得到了个数据行先测试Col会有个数据行需要检查它们找到其中的个与col中的值匹配记录其中就有次是失败了先测试col会有个数据行需要检查它们找到其中的个与col中的值匹配的记录只有次是失败的因此需要的计算和磁盘I/O更少其结果是优化器会先测试col因为这样做开销更小