mysql性能优化神器 -- Explain

一、简单使用

explain + 查询语句 + \G(格式化,可选);例:
index_demo
各列含义解释:
1. id: SELECT 查询的标识符. 每个 SELECT 都会自动分配一个唯一的标识符。
2. select_type: SELECT 查询的类型。
3. table: 查询的是哪个。
4. partitions: 匹配的分区。
5. type: join 类型。
6. possible_keys: 此次查询中可能用到的索引。
7. key: mysql决定使用哪个索引来优化此查询, 用不上索引其值为NULL。
8. ref: 哪个字段或常数与 key 一起被使用。
9. rows: 为了找到所需要的数据,预计需要读取数据行数。( 这个是一个估计值,通常小比大好,影响结果集跟实际需要返回的数据行数约接近,效果越好)。
10. filtered: 表示此查询条件所过滤的数据的百分比。
11. extra: 额外的信息。

二、比较重要的字段

1、select_type

select_type 表示了查询的类型, 它的常用取值有:

  1. SIMPLE, 表示此查询不包含 UNION 查询或子查询
  2. PRIMARY, 表示此查询是最外层的查询
  3. UNION, 表示此查询是 UNION 的第二或随后的查询
  4. DEPENDENT UNION, UNION 中的第二个或后面的查询语句, 取决于外面的查询
  5. UNION RESULT, UNION 的结果
  6. SUBQUERY, 子查询中的第一个 SELECT
  7. DEPENDENT SUBQUERY: 子查询中的第一个 SELECT, 取决于外面的查询. 即子查询依赖于外层查询的结果。

最常见的查询类别应该是 SIMPLE 了, 比如当我们的查询没有子查询, 也没有 UNION 查询时, 那么通常就是 SIMPLE 类型。

2、type 查询类型,

type 提供判断查询是否高效的重要依据依据

  1. system: 表中只有一条数据. 这个类型是特殊的 const 类型。
  2. const: 针对主键或唯一索引的等值查询扫描, 最多只返回一行数据. const 查询速度非常快, 因为它仅仅读取一次即可。
  3. eq_ref: 通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查询的比较操作通常是 =, 查询效率较高。
  4. ref: 通常出现在多表的 join 查询, 针对于非唯一或非主键索引, 或者是使用了最左前缀规则索引的查询。
  5. range(范围查找): 表示使用索引范围查询, 通过索引字段范围获取表中部分数据记录. 这个类型通常出现在 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN() 操作中。当 type 是 range 时, 那么 EXPLAIN 输出的 ref 字段为 NULL, 并且 key_len 字段是此次查询中使用到的索引的最长的那个。
  6. index(扫描整个索引): 表示全索引扫描(full index scan), 和 ALL 类型类似, 只不过 ALL 类型是全表扫描, 而 index 类型则仅仅扫描所有的索引, 而不扫描数据。index 类型通常出现在: 所要查询的数据直接在索引树中就可以获取到, 而不需要扫描数据. 当是这种情况时, Extra 字段 会显示 Using index(覆盖索引)。
  7. ALL(全表扫描): 表示全表扫描, 这个类型的查询是性能最差的查询之一. 通常来说, 我们的查询不应该出现 ALL 类型的查询, 因为这样的查询在数据量大的情况下, 对数据库的性能是巨大的灾难. 如一个查询是 ALL 类型查询, 那么一般来说可以对相应的字段添加索引来避免.

通常来说, 不同的 type 类型的性能关系如下:
system > const > eq_ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
尽量把index和type去掉。

3、key_len

key_len : mysql使用到的索引的长度(组合索引可能只会用到部分索引字段,这个字段可以评估组合索引是否完全被使用,或只有最左部分字段被使用到,所以key_len不等于索引真实长度)不影响查询精度效率前提下越短越好。

key_len 的计算规则如下:

  • 字符串
    • char(n): n 字节长度
    • varchar(n): 如果是 utf8 编码, 则是n + 2字节
    • 不同的字符集,一个字符占用的字节数不同
      • latin1编码的,一个字符占用一个字节
      • gbk编码的,一个字符占用两个字节
      • utf8编码的,一个字符占用三个字节

例如:一个utf8的 : ‘name’ varchar(32) NOT NULL,索引所占字节数为:3*32 + 2 = 98个字节

  • 数值类型:

    • TINYINT: 1字节
    • SMALLINT: 2字节
    • MEDIUMINT: 3字节
    • INT: 4字节
    • BIGINT: 8字节
  • 时间类型

    • DATE: 3字节
    • TIMESTAMP: 4字节
    • DATETIME: 8字节

字段属性: NULL 属性 占用一个字节. 如果一个字段是 NOT NULL 的, 则不占字节。

4、Extra

EXplain 中的很多额外的信息会在 Extra 字段显示, 常见的有以下几种内容:

  1. Using filesort(文件排序) : 当 Extra 中有 Using filesort 时, 表示 MySQL 需额外的排序操作, 不能通过索引顺序达到排序效果. 一般有 Using filesort, 都建议优化去掉, 因为这样的查询 CPU 资源消耗大。
  2. Using index(覆盖索引) : “覆盖索引扫描”, 表示查询在索引树中就可查找所需数据, 不用扫描表数据文件, 往往说明性能不错。
  3. Using temporary(临时表) : 查询有使用临时表, 一般出现于排序, 分组和多表 join 的情况, 查询效率不高, 建议优化。
  4. using where : 限制匹配哪些行。
  5. using index condition : where包含部分索引/distinct/NULL 。

Using where、Using index,、覆盖索引+扫面全部索引(type:index),使用到部分索引

猜你喜欢

转载自blog.csdn.net/qq_37502106/article/details/80208692