zoukankan      html  css  js  c++  java
  • explain解析

    MySQL执行计划调用方式
    执行计划包含的信息
    执行计划显示内容解读
    MySQL执行计划的局限
    MySQL5.6支持OPTIMIZER_TRACE

    1.什么是归并排序
    将已有序的子序列合并,得到完全有序的序列

    2.执行计划中Using temporaryusing filesort的区别?
    Using temporary
    表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
    这个值表示使用了内部临时(基于内存的)表。一个查询可能用到多个临时表。有很多原因都会导致MySQL在执行查询期间创建临时表。
    两个常见的原因是在来自不同表的上使用了DISTINCT,或者使用了不同的ORDER BY和GROUP BY列。可以强制指定一个临时表使用基于
    磁盘的MyISAM存储引擎。这样做的原因主要有两个:
    1)内部临时表占用的空间超过min(tmp_table_size,max_heap_table_size)系统变量的限制
    2)使用了TEXT/BLOB 列
    using filesort
    MySQL中无法利用索引完成的排序操作称为“文件排序”--filesort算法,有可能在内存排序,也可能利用磁盘

    Using where; Using temporary; Using filesort:表示进行关联查询时(mysql中关联查询的概念要更宽泛,不仅仅指两张表的关联才叫关联查询),
    使用了临时表,并在生成临时表后,又进行了文件排序;
    Using where; Using temporary表示,仅仅生成了临时表,而没有进行文件排序(在生成临时表的时候已经排序完毕了)。

    filesort:跟file没有关系,只是sort,如果无法使用index进行排序时,数据库会额外的进行数据排序
    需要注意的是:由于 Using filesort是使用算法在 内存中进行排序,MySQL对于排序的记录的大小也是有做限制:max_length_for_sort_data,默认为1024
    show variables like '%max_length_for_sort_data%';
    如果排序查询的数据两大于这个默认值的话,还是会使用Using filesort,当排序查询的数据量在默认值的范围内是,在排序的字段上加上索引可以提升MySQL查询的速度
    where u.id=100 order by u.update_time
    idx_user_id_update_time(id,update_time)
    磁盘临时表和文件排序
    内存临时表,myisam磁盘临时表

    3.表中只有一条数据,为什么在执行计划中也会有using filesort?(实验测试)
    (system@127.0.0.1:3306) [test]> explain select * from t22 where id=1 order by name;
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
    | 1 | SIMPLE | t22 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where; Using filesort |

    覆盖索引(Covering Index)
    MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件
    包含所有满足查询需要的数据的索引称为 覆盖索引(Covering Index)
    注意:
    如果要使用覆盖索引,一定要注意select列表中只取出需要的列,不可select *,因为如果将所有字段一起
    做索引会导致索引文件过大,查询性能下降
    Using where
    表示MySQL服务器在存储引擎受到记录后进行“后过滤”(Post-filter),
    如果查询未能使用索引,Using where的作用只是提醒我们MySQL将用where子句来过滤结果集

    MySQL执行计划的局限
    EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
    ? EXPLAIN不考虑各种Cache
    ? EXPLAIN不能显示MySQL在执行查询时所作的优化工作
    ? 部分统计信息是估算的,并非精确值(如:对Innodb行数的估算)
    ? EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划(5.6.*版本已经可以对
    update,delete操作做EXPALIN)

    MySQL5.6支持OPTIMIZER_TRACE

    Explain 详解
    使用一个示例 SQL 来解释 explain :
    select id from r_ibeacon_biz_device_d where ftime >= 20151126 and ftime <= 20151126 and biz_id = 11602 limit 50;
    IDX_BID_FTIME<biz_id, ftime>是表r_ibeacon_biz_device_d的其中一条索引。
    Biz_id,ftime 均为 bigint 类型。
    我们着重关注几个重点字段的重点值:
    - type: 索引的使用方式
    eq_ref … 索引,关联匹配若干行 ,最多只会有一条匹配结果,一般是通过主键或唯一键索引来访问
    ref … 索引(前缀)匹配 ,JOIN语句中驱动表索引引用的查询
    ref_or_null 与ref的唯一区别就是在使用索引引用的查询之外再增加一个空值的查询
    index_merge 查询中同时使用两个(或更多)索引,然后对索引结果进行合并(merge),再读取表数据。这种连接类型意味着使用了Index Merge优化方法
    range … 索引范围扫(BETWEEN、IN、>=、LIKE)得到数据
    index … 索引全扫描
    unique_subquery 子查询中的返回结果字段组合是主键或唯一约束
    index_subquery 子查询中的返回结果字段组合是一个索引(或索引组合),但不是一个主键或唯一索引。
    all … 表全扫描
    示例中使用的索引是使用全索引范围扫描,所以 type 为 range
    - possible_keys:适用查询的索引列表。示例中有三条索引适用本次查询。
    - key: 查询实际执行使用的索引。示例使用的为 IDX_BID_FTIME
    - key_len:查询使用索引的长度。
    null 1字节
    tinyint 1字节
    int 4字节
    bigint 8字节
    double 8字节
    datetime 8字节
    timestamp 4字节
    varchr(10)变长字段且允许NULL: 10*(Character
    Set:utf8=3,gbk=2,latin1=1)+1(NULL)+2(变长字段)
    char(10)固定字段且允许NULL: 10*(Character
    Set:utf8=3,gbk=2,latin1=11(NULL)

    以上是常用类型的长度,示例中key_len为 18,即:8 字节 (biz_id bigint)+1 字节 ( biz_id 允许为 null )
    +8 字节 ( ftimebigint )+1 字节 ( ftime 允许为 null )。所以本次查询是使用了索引的所有字段加速查询

    - rows:查询预估扫描的行数

    常见问题汇总结
    - Range 怎么使用索引?
    详见上文
    - Order by使用索引吗?
    该问题可以由以下资料解释:
    SQL queries with an order by clause don’t need to sort the result explicitly if the relevant index already delivers the
    rows in the required order. That means the same index that is used for the where clause must also cover the order by clause.
    总之一句话:索引本身并不能避免排序,当根据索引取出的数据已经满足 order by 子句的要求就可以避免排序操作。
    - order by太慢?
    避免数据排序,采用索引排序 (分页查询文艺写法)
    `- limit offset太慢?
    避免大 offset,使用 where 语句过滤更多的行。
    - 为什么不走索引(索引也走了,还是慢)?
    类型是否一致: int vs char(varchar)、varchar(32)vs varchar(64)
    字符集是否一致:涉及表关联时,两表字符集是否一致。

  • 相关阅读:
    程序员必定会爱上的10款软件(转)
    用代码来细说Csrf漏洞危害以及防御
    UPX源码分析——加壳篇
    从零开始学习渗透Node.js应用程序
    自己动手python打造渗透工具集
    国内国外最好的java开发论坛及站点 [转]
    运维无小事之一次导致数据丢失的小变更
    使用python及工具包进行简单的验证码识别
    浅析企业安全中账户安全 的重要性
    全世界最顶级黑客同时沸腾在DEF CON 25,是怎样一种体验?
  • 原文地址:https://www.cnblogs.com/yhq1314/p/10266656.html
Copyright © 2011-2022 走看看