• MySQL Explain 详解(新) 性能优化必杀技


    近期有个产品的统计信息超过了2000万行,后台的查询直接超时了,单纯sql在命令行执行都需要20s以上。用EXPLAIN后发现因为索引太多这条SQL没有用上计划的索引,更改后直接秒级出结果,下面看看EXPLAIN(Navicat里的解释按钮同样效果)的威力。
    explain执行后的效果大致如下:

    mysql> explain select * from student where classid=1;
    +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
    | id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
    +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
    |  1 | SIMPLE      | student | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    4 |    25.00 | Using where |
    +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
    1 row in set, 1 warning (0.00 sec)
    

    总共有12列,分别是id、select_type、table、partitions、type、possible_keys、key、key_len、ref、rows、filtered、Extra,其中在我看来最重要的是key列和extra列。
    key直接显示有没有使用索引,extra显示是否根据条件查询、有没有利用文件排序等。
    能够把SQL优化(修改)到使用索引基本上就可以通吃绝大多数情况了。

    列名 解释
    id 查询的唯一标识
    select_type 查询类型
    table 查询的那个表
    partitions 匹配的分区
    type join类型
    possible_keys 可能使用的索引
    key 最终使用的索引
    key_len 最终使用的索引的长度
    ref 与索引一起被使用的字段或常数
    rows 查询扫描的行数,是个估算值
    filtered 查询条件所过滤的数据的百分比
    Extra 额外的信息

    1、id

    查询的唯一标识,当这行是联合查询中的被驱动的表时这个值是Null。

    2、select_type的可能的值有如下:

    解释
    SIMPLE 表示此查询不包含 UNION 查询或子查询
    PRIMARY 表示此查询是最外层的查询
    UNION 表示此查询是 UNION 的第二或随后的查询
    DEPENDENT UNION UNION 中的第二个或后面的查询语句, 取决于外面的查询
    UNION RESULT UNION 的结果
    SUBQUERY 子查询中的第一个 SELECT
    DEPENDENT SUBQUERY 子查询中的第一个 SELECT, 取决于外面的查询. 即子查询依赖于外层查询的结果
    DERIVED 驱动表
    MATERIALIZED 子查询的实现(Materialized subquery)
    UNCACHEABLE SUBQUERY 不能被缓存的子查询
    UNCACHEABLE UNION 在联合查询中的且不能被缓存的子查询中的后续查询

    3. table

    查询涉及的表名。

    4. partitions

    查询的记录所在的分区,如果表没有被拆分这个值是Null。

    5. type

    连接的类型,不同的类型及说明如下:

    解释
    system 这是下面类型const的一种特殊情况。表里只有一条数据。
    const 针对主键或者索引的等值查询,该表最多有一个匹配的行,由于只有一行,因此该行中列的值可以被优化器的其余部分视为常量。
    eq_ref 当连接使用索引的所有部分并且索引是a PRIMARY KEY或UNIQUE NOT NULL索引时。
    ref 所有具有匹配索引值的行都从这个表中读取
    fulltext 使用FULLTEXT 索引执行
    ref_or_null ref的基础上包含了NULL值的搜索
    index_merge 使用索引合并优化
    unique_subquery 只是一个索引查找函数,可以完全替代子查询以提高效率。
    index_subquery 取代了IN子查询,但它适用于非唯一索引的子查询。
    range 只有在给定范围内的行才能被检索,使用索引来选择行。的key 输出行中的列指示使用哪个索引。将key_len包含已使用的时间最长的关键部分。该ref列是 NULL用于这种类型的。
    index 使用索引查找,如在Extra列看到Using index,说明正在使用覆盖索引,只扫描索引的数据,它比按索引次序全表扫描的开销要小很多
    ALL 全表扫描

    6. possible_keys

    可能被使用的索引,如果此列是NULL,则表示没有相关的索引,可以通过WHERE 子句来检查是否引用某些适合索引或列,从而提高查询的性能。
    要查看表有哪些索引,请使用 SHOW INDEX FROM tbl_name

    7. key

    上面的possible_keys是可能被使用的key,这个式实际被使用的键。
    如果 key是NULL,表示MySQL没有发现有索引可以用于更有效地执行查询。要强制MySQL使用索引或忽略索引,可以使用FORCE INDEX,USE INDEXIGNORE INDEX语句。

    8. key_len

    被使用索引的长度。取决于key列,如果key为NULL,这列也是NULL。

    9. ref

    该列显示将哪些列或常量与列中指定的索引进行比较,以 key从表中选择行。

    10. rows

    MySQL认为查询必须扫描的行数。
    对于InnoDB存储引擎,这个数字是估计值,并不总是准确的。

    11. filtered

    条件过滤后的行占表内总行数的百分比。

    12. Extra,

    表示MySQL解析查询的其他信息。
    Extra是EXPLAIN输出中另外一个很重要的列,该列显示MySQL在查询过程中的一些详细信息,MySQL查询优化器执行查询的过程中对查询计划的重要补充信息。

    解释
    Using filesort MySQL有两种方式可以生成有序的结果,通过排序操作或者使用索引,当Extra中出现了Using filesort 说明MySQL使用了后者,但注意虽然叫filesort但并不是说明就是用了文件来进行排序,只要可能排序都是在内存里完成的。大部分情况下利用索引排序更快,所以一般这时也要考虑优化查询了。使用文件完成排序操作,这是可能是ordery by,group by语句的结果,这可能是一个CPU密集型的过程,可以通过选择合适的索引来改进性能,用索引来为查询结果排序。
    Using temporary 用临时表保存中间结果,常用于GROUP BY 和 ORDER BY操作中,一般看到它说明查询需要优化了,就算避免不了临时表的使用也要尽量避免硬盘临时表的使用。
    Not exists MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行, 就不再搜索了。
    Using index 说明查询是覆盖了索引的,不需要读取数据文件,从索引树(索引文件)中即可获得信息。如果同时出现using where,表明索引被用来执行索引键值的查找,没有using where,表明索引用来读取数据而非执行查找动作。这是MySQL服务层完成的,但无需再回表查询记录。
    Using index condition 这是MySQL 5.6出来的新特性,叫做“索引条件推送”。简单说一点就是MySQL原来在索引上是不能执行如like这样的操作的,但是现在可以了,这样减少了不必要的IO操作,但是只能用在二级索引上。
    Using where 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。注意:Extra列出现Using where表示MySQL服务器将存储引擎返回服务层以后再应用WHERE条件过滤。
    Using join buffer 使用了连接缓存:Block Nested Loop,连接算法是块嵌套循环连接;Batched Key Access,连接算法是批量索引连接
    impossible where where子句的值总是false,不能用来获取任何元组
    select tables optimized away 在没有GROUP BY子句的情况下,基于索引优化MIN/MAX操作,或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
    distinct 优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作。

    参考
    http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/explain-output.com.coder114.cn.html#explain-extra-information
    https://www.jianshu.com/p/ea3fc71fdc45
    http://www.deituicms.com/mysql8cn/cn/web.html

  • 相关阅读:
    SharePoint 疑难杂症之加载控件TaxonomyPicker.ascx失败及其解决方法
    SQL Server、Oracle、db2所提供的简装版(Express)比较
    试水Windows 8 Metro application(xaml)及我的一些理解
    基于OAuth实现的Windows Live Writer新浪微博插件
    fmplan主页功能设计第一阶段成果
    MVC3课程中的几个问题整理
    【十五分钟Talkshow】为什么新浪微博的输入文本框具有记忆功能
    参照WPF实现Silverlight中的多值绑定特性
    MVVM、MVVMLight、MVVMLight Toolkit之我见
    面向服务的RIA应用系统开发中的异常处理
  • 原文地址:https://www.cnblogs.com/gudao119/p/13270013.html
Copyright © 2020-2023  润新知