not exists: 在左连接中,优化器可以通过改变原有的查询组合而使用的优化方法。当发现一个匹配的行之后,不再为前面的行继续检索,可以部分减少数据访问的次数。例如,表t1、t2,其中t2.id为not null,对于SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;由于 t2.id非空,所以只可能是t1中有,而t2中没有,所以其结果相当于求差。left join原本是要两边join,现在Mysql优化只需要依照 t1.id在t2中找到一次t2.id即可跳出。
const row not found: 涉及到的表为空表,里面没有数据。
Full scan on NULL key: 是优化器对子查询的一种优化方式,无法通过索引访问NULL值的时候会做此优化。
Impossible Having: Having子句总是false而不能选择任何列。例如having 1=0
Impossible WHERE: Where子句总是false而不能选择任何列。例如where 1=0
Impossible WHERE noticed after reading const tables: mysql通过读取“const/system tables”,发现Where子句为false。也就是说:在where子句中false条件对应的表应该是const/system tables。这个并不是mysql通过统计信息做出的,而是真的去实际访问一遍数据后才得出的结论。当对某个表指定了主键或者非空唯一索引上的等值条件,一个query最多只可能命中一个结果,mysql在explain之前会优先根据这一条件查找对应记录,并用记录的实际值替换query中所有用到来自该表属性的地方。例如:select * from a,b where a.id = 1 and b.name = a.name 执行过程如下:先根据a.id = 1找到一条记录(1, 'name1'),然后将b.name换成'name1',然后通过a.name = 'name1'查找,发现没有命中记录,最终返回“Impossible WHERE noticed after reading const tables”。
No matching min/max row: 没有行满足如下的查询条件。例如:EXPLAIN SELECT MIN(actor_id) FROM actor WHERE actor_id > 3(只有两条记录)actor_id为唯一性索引时,会显示“No matching min/max row”,否则会显示“using where”。
no matching row in const table: 对一个有join的查询,包含一个空表或者没有数据满足一个唯一索引条件。
No tables used: 查询没有From子句,或者有一个From Dual(dual:虚拟表,是为了满足select...from...习惯)子句。例如:EXPLAIN SELECT VERSION()
Range checked for each record (index map: N): Mysql发现没有好的index,但发现如果进一步获取下一张join表的列的值后,某些index可以通过range等使用。Mysql没找到合适的可用的索引。取代的办法是,对于前一个表的每一个行连接,它会做一个检验以决定该使用哪个索引(如果有的话),并且使用这个索引来从表里取得记录。这个过程不会很快,但总比没有任何索引时做表连接来得快。
Select tables optimized away: 当我们使用某些聚合函数来访问存在索引的某个字段时,优化器会通过索引直接一次定位到所需要的数据行完成整个查询。在使用某些聚合函数如min,max的query,直接访问存储结构(B树或者B+树)的最左侧叶子节点或者最右侧叶子节点即可,这些可以通过index解决。Select count(*) from table(不包含where等子句),MyISAM保存了记录的总数,可以直接返回结果,而Innodb需要全表扫描。Query中不能有group by操作。
unique row not found: 对于SELECT … FROM tbl_name,没有行满足unique index或者primary key。从表中查询id不存在的一个值会显示Impossible WHERE noticed after reading const tables。
Using filesort: 指Mysql将用外部排序而不是按照index顺序排列结果。数据较少时从内存排序,否则从磁盘排序。Explain不会显示的告诉客户端用哪种排序。
Using index: 表示Mysql使用覆盖索引避免全表扫描,不需要再到表中进行二次查找数据。注意不要和type中的index类型混淆。
Using index for group-by: 类似Using index,所需数据只需要读取索引,当query中有group by或distinct子句时,如果分组字段也在索引中,extra就会显示该值。
Using temporary: Mysql将创建一个临时表来容纳中间结果。在group by和order by的时,如果有必要的话。例如group by一个非键列,优化器会创建一个临时表,有个按照group by条件构建的unique key,然后对于每条查询结果(忽略group by),尝试insert到临时表中,如果由于unique key导致insert失败,则已有的记录就相应的updated。例如,name上没有索引,SELECT name,COUNT(*) FROM product GROUP BY name,为了排序,Mysql就需要创建临时表。此时一般还会显示using filesort。