mysql总结之explain(3)

range:在一定范围内扫描索引。如where中带有between或者>,此时ref列为NULL。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range。

index:按索引次序扫描数据。因为按照索引扫描所以会避免排序,但也会扫描整表数据,若随机读取开销会更大。如果extra列显示using index,说明使用的是覆盖索引(覆盖索引:包含所有满足查询需要的数据列的索引)。对于InnoDB表特别有用,此时只访问索引数据即可,不用再根据主键信息获取原数据行,避免了二次查询,而MyISAM表优化效果相对InnoDB来说没有那么的明显。

all:按行扫描全表数据,除非查询中有limit或者extra列显示使用了distinct或notexists等限定词。

Extra信息 :

distinct:当mysql找到第一条匹配的结果值时,就停止该值的查询,然后继续该列其他值的查询。

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就会显示该值。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/8232a6c7be992f40aba765facee8cd37.html