type列值详解 - xiaoboluo768/qianjinliangfang GitHub Wiki

  • EXPLAIN输出的类型列描述查询表如何连接。 在JSON格式的输出中,type列值对应access_type属性的值。 以下列出type列可能出现的连接类型值,顺序从最佳到最差
    • system:查询的表中只有一行数据。 这是const连接类型的一种特殊情况(表中只有一行数据或者是空表,且只能用于myisam和memory表,如果是innodb表,则在5.6之前的版本,多数时候可能为all或者index,在5.6之后的版本中,有一行数据时显示为const,没有数据时显示为null)
    • const:查询的表最多只有一个匹配的行, 因为只有一行,所以该行中的列的值可以被优化程序视为常量(使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描)。const类型查询非常快,当使用PRIMARY KEY或UNIQUE索引的所有列进行查询时(与常量值进行比较时),将使用const(因为主键和唯一索引能够保证值唯一)。tbl_name可以用作const表的示例:SELECT * FROM tbl_name WHERE primary_key = 1;SELECT * FROM tbl_name WHERE primary_key_part1 = 1 AND primary_key_part2 = 2;
    • eq_ref:出现在要连接多个表的查询计划中,被驱动表(或者说连接嵌套中的前一个表)中的每一行在与驱动表(或者说连接嵌套中的后一个表)的数据查询结果集匹配中只有一行数据匹配时,且这行数据是第二个表的主键或者唯一索引,且必须为not null,该表查询类型为eq_ref。如果使用到的索引是多列索引,那么只有当索引的所有列都被连接查询使用到且索引为PRIMARY KEY或UNIQUE NOT NULL索引时才会出现eq_ref。 使用column=比较运算符的形式也可以使用到索引列, MySQL可以使用eq_ref连接来处理ref_table的示例:SELECT * FROM ref_table,other_table WHERE ref_table.key_column = other_table.column; SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1 = other_table.column AND ef_table.key_column_part2 = 1;
    • ref:不像eq_ref那样要求连接顺序,也没有主键和唯一索引的要求,只要使用相等条件检索时就可能出现,常见与辅助索引的等值查找,或者多列主键、唯一索引中,使用第一个列之外的列作为等值查找也会出现,或者使用最左前缀索引查找中也可能会出现。总之,返回数据不唯一的等值查找就可能出现,换句话说,如果连接不能基于key匹配单个行,则使用ref
      • ref可以用于使用=或<=>运算符进行比较的索引列。 MySQL可以使用ref连接来处理ref_table的示例:SELECT * FROM ref_table WHERE key_column=expr; SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column; SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1;
    • fulltext:使用FULLTEXT索引执行连接查询(要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引)
    • ref_or_null:这种连接类型类似于ref,但MySQL还会额外搜索包含NULL值的行。此连接类型优化最常用于解析子查询(与ref方法类似,只是增加了null值的比较。实际用的不多)。MySQL可以使用ref_or_null连接来处理ref_table的示例:SELECT * FROM ref_table WHERE key_column = expr或key_column IS NULL;
    • index_merge:此连接类型表示使用索引合并优化。 在这种情况下,explain输出行中的key列包含index_merge优化所使用的索引列表(表示查询使用了两个以上的索引,最后取交集或者并集,常见and ,or的条件使用了不同的索引),而key_len使用最长索引部分来计算(注意:实际查询中由于可能要读取多个索引,性能可能大部分时间还不如range,有些业内人士建议排在range之后)
    • unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值,如: value IN(SELECT primary_key FROM single_table WHERE some_expr),其中IN子句中的select字段是为IN子句中的查询的主键或唯一索引。
    • index_subquery:此连接类型与unique_subquery类似。 用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重:value IN(SELECT key_column FROM single_table WHERE some_expr),其中IN子句中的select字段为IN子句中的查询的一个非唯一索引的Key
    • range:使用索且只检索指定范围内的行,explain输出行中的key列显示了使用哪个索引, key_len列按照所使用的索引最长部分进行计算。range类型查询的explain输出行中的type的值为NULL,当使用=,<>,>,> =,<,<=,IS NULL,<=>,like,BETWEEN或IN()运算符+一个常量值或表达式返回一个常量值时,会使用range类型查询,示例:SELECT * FROM tbl_name WHERE key_column = 10; SELECT * FROM tbl_name WHERE key_column BETWEEN 10和20; SELECT * FROM tbl_name WHERE key_column IN(10,20,30); SELECT * FROM tbl_name WHERE key_part1 = 10 AND key_part2 IN(10,20,30);
    • index:除了扫描索引树这种情况之外,其他的index连接类型与ALL类型相同。index有如下两种方式:
      • 如果索引是查询的覆盖索引,并且可以用于满足查询所需的所有数据,则查询只扫描索引树。在这种情况下,Extra列显示Using index。index扫描通常比ALL快,因为索引的大小通常小于全表数据
      • 使用索引读取来执行全表扫描,以按索引顺序查找数据行。在这种情况下,Extra列不会出现Using index
      • 当查询仅使用单个索引的部分索引时,MySQL可以使用此连接类型
  • ALL:这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。通常,可以通过添加索引来避免ALL

上一篇:执行计划输出列含义详解 | 下一篇:Extra列值详解

⚠️ **GitHub.com Fallback** ⚠️