Mysql 将select 查询氛围简单和复杂类型,复杂类型可分为三大类:简单子查询、所谓的派生表(在from子句中的子查询,以及union查询。
select_type 列
SIMPLE值意味着查询不包括子查询和UNION
PRIMAY查询有任何复杂的子部分,最外层部分标记为PRIMAY
SUBQUERY包含在SELECT列表中的子查询的SELECT(换句话说,不在FROM子句中)标记为SUBQUERY
DERIVED值用来表示包含在FROM子句的子查询中的SELECT,MYSQL会递归执行并将结果放在一个临时表中。服务器内部称其为派生表,因为该临时表是从子查询中派生来的。
UNION在UNION中的第二个和随后的SELECT被标记为UNION
UNION RESULT用来从UNION的匿名临时表检索结果的SELECT被标记为UNION RESULT
TYPE列
更准确的说法应该是 访问类型—-Mysql 决定如何查询表中的行。访问方法,依次从最差到最优
ALL全表扫描 意味着Mysql 必须扫描整张表,从头到尾,去找到需要的行。(这里也有例外,例如查询里使用了LIMIT,或者Extra列中
显示“Using distinct/not exists”)
Index这个跟全表扫描一样,只是Mysql扫描表时按索引次序进行而不是行。它的主要优点是避免排序;最大的缺点是要承担按索引次序读取整个表的开销。这通常意味着若按随机次序访问行,开销将会非常大。
如果在Extra列中看到“Using index ” 说明Mysql 正在使用覆盖索引,而不是按索引次序的每一行。它比按索引次序全表扫描的开销要少很多。
range范围扫描就是一个有限制的索引扫描,它开始于索引里的某一点,返沪匹配这个值域的行。这比全索引扫描好一些,因为它用不着遍历全部索引。显而易见的范围扫描是带有BETWEEN 或 在WHERE子句里带有 > 的查询。
当mysql 使用索引去查询一系列值时,例如IN() 和OR列表,也会显示为范围扫描。然而,这两者其实是相当不同的访问类型,在性能上有重要的差异。第五章 “什么是范围查询”
Ref这是一种索引访问(有时也叫做索引查询),它返回所有匹配某个单个值的行。然而,它可能会找到多个符合条件的行,因此,她是查找和扫描的混合体。此类索引访问只有当使用非唯一性索引或者唯一性索引的非唯一性前缀时才会发生。
Eq_ref 使用这种索引查询,Mysql知道最多只返回一条符合条件的记录。这种访问方法可以在Mysql使用主键或者唯一性索引查询时看到,它会将他们与某个参考值做比较。mysql对于这类访问类型的优化做的非常好,因为它知道无须估计匹配行的范围或在找到匹配行后再继续查找。
const,system 当Mysql 能对查询的某部分进行优化并将其转换成一个常量时,他就会使用这些访问类型。
NULL这种访问方式意味着Mysql 能在优化阶段分解查询语句,在执行阶段甚至用不着再访问表或者索引。
possible_keys列
这一列显示了查询可以使用哪些索引,这是基于查询访问的列和使用的比较操作符来判断的。这个列实在优化过程的早期创建的,因此有些罗列出来的索引可能对于后续优化过程是没用的。
key列
这一列显示了MySQL 决定采用哪些索引来优化对该表的访问 .如果该索引没有出现在possible_keys 列中,那么MySQL 选用它是处于另外的原因— 例如,他可能选择了一个覆盖索引,哪怕没有WHERE子句。
换句话说,possible_keys 揭示了哪一个索引能有助于高效的行查询,而key显示的是优化采用哪一个索引可以最小化查询成本。
key_len列
该列显示了MySQL在索引里使用的字节数。
ref列
显示了之前的表在key列记录的索引中查找值所用的列或常量。
rows列
这一列是MySQL 估计为了找到所需的行而要读取的行数。通过把所有rows列的值相乘,可以粗略的估算出整个查询会检查的行数。
Extra列
这一列包含的是不合适在其他列显示的额外信息。 常见的最重要的值如下:
Using index 表示MySQL将使用覆盖索引,一避免访问表。不要把覆盖索引和index访问类型弄混了。
Using where这意味着MySQL服务器将在存储引擎检索后再进行过滤。许多WHERE条件里涉及索引中的列,当它读取索引时,就能被存储引擎检验,因此不是所有带WHERE子句的查询都会显示“Using where”.
Using temporary这意味着MySQL在对查询结果进行排序时会使用一个临时表。
Using filesort意味着MySQL会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。
网友评论