转:MySQL性能优化神器Explain使用分析

详细请点击 https://blog.csdn.net/qq_38293564/article/details/80883704

以下是自己总结;

接下来我们来重点看一下比较重要的几个字段

type

type类型的性能比较

通常来说,不同的 type 类型的性能关系如下: 
ALL < index < range ~ index_merge < ref < eq_ref < const < system 
ALL 类型因为是全表扫描,因此在相同的查询条件下,它是速度最慢的。 
而 index 类型的查询虽然不是全表扫描,但是它扫描了所有的索引,因此比 ALL 类型的稍快。 
后面的几种类型都是利用了索引来查询数据,因此可以过滤部分或大部分数据,因此查询效率就比较高了。

    • system: 表中只有一条数据,这个类型是特殊的 const 类型。
    • const: 针对主键或唯一索引的等值查询扫描,最多只返回一行数据。const 查询速度非常快,因为它仅仅读取一次即可。 
      例如下面的这个查询,它使用了主键索引,因此 type 就是 const 类型的:explain select * from user_info where id = 2\G;
    • eq_ref: 此类型通常出现在多表的 join 查询,表示对于前表的每一个结果,都只能匹配到后表的一行结果,并且查询的比较操作通常是 =,查询效率较高。例如:EXPLAIN SELECT * FROM user_info,order_info WHERE user_info.id = order_info.user_id\G;
    • ref: 此类型通常出现在多表的 join 查询,针对于非唯一或非主键索引,或者是使用了 最左前缀 规则索引的查询。 
      例如下面这个例子中,就使用到了 ref 类型的查询:EXPLAIN SELECT * FROM user_info,order_info WHERE user_info.id = order_info.user_id AND order_info.user_id = 5\G;
    • range: 表示使用索引范围查询,通过索引字段范围获取表中部分数据记录。这个类型通常出现在 =, <>,>,>=,<,<=,IS NULL,<=>,BETWEEN,IN() 操作中。 
      当 type 是 range 时,那么 EXPLAIN 输出的 ref 字段为 NULL,并且 key_len 字段是此次查询中使用到的索引的最长的那个。例如下面的例子就是一个范围查询:EXPLAIN SELECT * FROM user_info WHERE id BETWEEN 2 AND 8\G;
    • index: 表示全索引扫描(full index scan),和 ALL 类型类似,只不过 ALL 类型是全表扫描,而 index 类型则仅仅扫描所有的索引,而不扫描数据。 
      index 类型通常出现在:所要查询的数据直接在索引树中就可以获取到,而不需要扫描数据,当是这种情况时,Extra 字段 会显示 Using index。例如:EXPLAIN SELECT name FROM user_info \G;上面的例子中,我们查询的 name 字段恰好是一个索引,因此我们直接从索引中获取数据就可以满足查询的需求了,而不需要查询表中的数据. 因此这样的情况下,type 的值是 index,并且 Extra 的值是 Using index。
    • ALL: 表示全表扫描,这个类型的查询是性能最差的查询之一。通常来说,我们的查询不应该出现 ALL 类型的查询,因为这样的查询在数据量大的情况下,对数据库的性能是巨大的灾难. 如一个查询是 ALL 类型查询,那么一般来说可以对相应的字段添加索引来避免。 
      下面是一个全表扫描的例子,可以看到,在全表扫描时,possible_keys 和 key 字段都是 NULL,表示没有使用到索引,并且 rows 十分巨大,因此整个查询效率是十分低下的。EXPLAIN SELECT age FROM user_info WHERE age = 20 \G;

Extra

    • Using filesort 
      当 Extra 中有 Using filesort 时,表示 MySQL 需额外的排序操作,不能通过索引顺序达到排序效果。一般有 Using filesort 都建议优化去掉,因为这样的查询 CPU 资源消耗大。 
      例如下面的例子:EXPLAIN SELECT * FROM order_info ORDER BY product_name \G;
      我们的索引是KEY `user_product_detail_index` (`user_id`, `product_name`, `productor`)
      但是上面的查询中根据 product_name 来排序,因此不能使用索引进行优化,进而会产生 Using filesort。 
      如果我们将排序依据改为 ORDER BY user_id, product_name,那么就不会出现 Using filesort 了。例如:EXPLAIN SELECT * FROM order_info ORDER BY user_id, product_name \G;
    • Using index 
      “覆盖索引扫描”,表示查询在索引树中就可查找所需数据,不用扫描表数据文件,往往说明性能不错。
    • Using temporary 
      查询有使用临时表,一般出现于排序,分组和多表 join 的情况,查询效率不高,建议优化。

猜你喜欢

转载自www.cnblogs.com/zhangjian816/p/10860230.html