这里主要利用explain来观察语句是否走索引。
explain语法自行百度,详见Mysql官方文档。
一、explain输出格式说明
具体说明:
1) id
该字段标识select语句id,若SQL中只有1个select语句(即使是多表关联查询),则该值为1,否则依次递增;若SQL是union的结果,则该值为NULL。
2) select_type
该字段说明select语句的类型,其可能的取值如下图(来自官网文档):
其中,simple是最常见的类型,表明SQL只包含1个select语句;derived表明该行代表的数据表(derived table)其实是from子句中包含的子查询的输出结果;其余类型较易理解,阅读官方文档即可,这里不赘述。
3) table
该字段表明explain输出的每行所代表的数据集来自哪张表,其值通常是具体的表名,当数据集是union的结果时,其值可能
是<unionM,N>,当数据集来自derived table时,其值可能是<derivedN>。这里提到的M或N均是id字段的值。
4) type
该字段表明各表是如何被join的,其取值比较复杂,详细可参考官网文档。这里只列出最常见的几种取值。
a. system/const
const表明上述"table"字段代表的数据集中,最多只有1行记录命中本步执行计划的查询条件,例如这步执行计划的sql的where
子句以某张表的primary key或unique index与常数做比较时,该执行计划对应的type字段取值就是const。
system只是const值的一个特例,它表示本步执行计划要操作的数据集中只有1行记录。
它们只可能出现在单表查询SQL的type字段取值中。
b. eq_ref
该值表明本步执行计划操作的数据集中关联字段是索引字段且只有1条记录符合上步执行计划操作的数据集的关联条件。这
是对多表做关联查询时,可能得到的最优的join类型(因为它通常表明关联的字段是本步执行计划要操作的表的primary key或unique index)。
c. ref
该值表明本步执行计划操作的数据集中关联字段是索引字段但不只有1条记录符合上步执行计划操作的数据集的关联条件。
符合关联条件的记录不只1条表明关联字段非primary key或unique index,当符合关联条件的记录数比较少时,这种join_type='ref'的场景还是比较合理的,但它显然不如join_type='eq_ref'高效。
d. ref_or_null
该join type类型与ref的场景类似,但它表明MySQL会对包含NULL值的字段做额外搜索。例如下面SQL的join type就是ref_or_null:
SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;
e. index_merge
该值表明MySQL会对本步执行计划进行index merge优化,触发index merge的SQL通常包含'or'操作,常见实例如下:
SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;
SELECT * FROM tbl_name WHERE (key1 = 10 OR key2 = 20) AND non_key=30;
SELECT * FROM t1, t2 WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%') AND t2.key1=t1.some_col;
SELECT * FROM t1, t2 WHERE t1.key1=1 AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2);
f. range
该值表明本步执行计划只操作单表且符合查询条件的记录不只1条,可能出现在有in或between操作的SQL中。
只限于单表操作场景也是其与前面提到的join_type取值为'ref'场景的区别,因为ref可能出现在单表/多表join操作场景下。
g. ALL
该值表明本步执行计划会对数据集做全表扫描,这是必须做优化的场景。通常可以通过对某些字段合理建索引来避免全表扫描。
h. index
该值表明MySQL执行本步计划时扫描的是index tree,而ALL则是扫全表。它可能在两种场景下出现:
case1. 本步计划查询数据集时select语句需要返回的字段是该数据集索引字段的最左前缀匹配集。如table A中已建立含2个字段的联合索引(f1, f2),则select f1 from A where f2 = 'yyy'可能会触发MySQL扫描index tree,这种情况下,执行计划的Extra字段会包含"Using index"来表明它扫描的是index tree,因为f1是(f1, f2)最终前缀匹配集中的1个元素;而select f2 from A where f2 = 'yyy'则会扫描全表。
case2. 本步计划按照索引顺序进行全表扫描来查找符合条件的数据。这种情况下,执行计划的Extra字段不会包含"Using index",这种全表扫描也是必须优化的场景。
5) possible_keys
该字段的值是可能被MySQL用作索引的字段,若值为NULL,则没有字段会被用作索引,因此查询效率不会高,这种情况下,需要优化数据表的索引结构。
6) key
该字段的值是MySQL真正用到的索引。
值得注意的是:该字段的值有可能不是possible_keys列出的候选索引字段,例如,当前查询SQL要返回的字段是数据表某索引字段的最左前缀匹配字段,但SQL的where条件中没有使用数据表的索引字段,则此时possible_keys可能为NULL,而key字段的值可能是那个能cover住待查询字段的数据表索引字段,此时,MySQL会扫描索引树,虽然低效,但比起扫描全表还是要快。这种场景也正是本文前面解释join_type='index'时提到的case1。
此外,在select语句中借助"force index或"use index"可以强制MySQL使用possible_keys中列出的候选索引字段。
7) key_len
该字段的值表明上述key字段的length,当MySQL将某联合索引字段作为SQL执行时用到的索引时,key_len字段可以暗示MySQL真正在什么程度上(多长的最左前缀匹配字段)使用了该联合索引。若key字段的值为NULL,则key_len字段值也为NULL。
8) ref
该字段的值表明数据表中的哪列或哪个constants会被用于与key字段指定的索引做比较。
9) rows
该字段的值表明MySQL执行该步计划对应的query时必须扫描的行数。这个值对于SQL优化非常具有参考意义,通常情况下,该值越小查询效率越高。
10) Extra
该字段的值包含了MySQL执行query时的其它额外信息。该字段可能的取值情况较多,详细情况可参考官网文档的说明。
该说明官网均有,既然有现成自己也就懒得翻译了。
PS:
字段说明参考网址:http://www.2cto.com/database/201502/377682.html
Mysql官方网址:http://dev.mysql.com/doc/refman/5.5/en/explain-output.html
二、其他问题
show index返回的字段意思:
1) Table 表的名称。
2) Non_unique 如果索引不能包括重复词,则为0,如果可以则为1。
3) Key_name 索引的名称
4) Seq_in_index 索引中的列序列号,从1开始。
5) Column_name 列名称。
6) Collation 列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。
7) Cardinality 索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。
8) Sub_part 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。
9) Packed 指示关键字如何被压缩。如果没有被压缩,则为NULL。
10) Null 如果列含有NULL,则含有YES。如果没有,则该列含有NO。
11) Index_type 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
12) Comment 多种评注,您可以使用db_name.tbl_name作为tbl_name FROM db_name语法的另一种形式。这两个语句是等价的:
mysql>SHOW INDEX FROM mytable FROM mydb;
mysql>SHOW INDEX FROM mydb.mytable;
http://www.th7.cn/db/mysql/201508/114301.shtml
SELECT /*!40001 SQL_NO_CACHE */ * FROM ... :
1 /*! */ 这是mysql 特里的语法,并非注释,因为里面达到条件也会执行。
2 !后面是版本号, 如果本数据库等于或大于此版本号,那么注释内的代码也会执行。
3 那么这句话的意思是 如果版本号大于或等于4,会执行 sql_no_cache, 就是不用缓存数据。 而并非说本次查询不作为下次查询的缓存。
4 在备份操作时Mysql 会自动调用此语法。
三、实践操作
自己项目就不展示了,安利一个网站。
推荐网址:http://tech.meituan.com/mysql-index.html(美团团队Mysql慢查询分析与解析,里面还详细讲了数据库使用的B+树)
来源:oschina
链接:https://my.oschina.net/u/2756867/blog/719504