zoukankan      html  css  js  c++  java
  • MySQL 执行计划详解

    (admin@g1-db-test-v07:5001)[jinhailan]>explain select * from t1;
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
    | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
    |  1 | SIMPLE      | t1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | NULL  |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
    

    explain输出

     id:在一个大的查询语句中每个SELECT关键字都对应一个唯一的id

    select_type:SELECT关键字对应的那个查询的类型

    table:表名

    partitions:匹配的分区信息

    type:针对单表的访问方法

    possible_keys:可能用到的索引

    key:实际使用的索引

    key_len:实际使用到的索引长度

    ref:当使用索引列等值查询时,与索引列进行等值匹配的对象信息

    rows:预估的需要读取的记录条数

    filtered:某个表经过搜索条件过滤后剩余记录条数的百分比

    Extra:一些额外的信息

    执行计划输出详解

    table

    不论我们的查询语句有多复杂,里边儿包含了多少个表,到最后也是需要对每个表进行单表访问的,EXPLAIN语句输出的每条记录都对应着某个单表的访问方法,该条记录的table列代表着该表的表名

    id

    查询语句中每出现一个SELECT关键字,设计MySQL的大叔就会为它分配一个唯一的id

    对于连接查询来说,一个SELECT关键字后边的FROM子句中可以跟随多个表,所以在连接查询的执行计划中,每个表都会对应一条记录,但是这些记录的id值都是相同的

    (admin@g1-db-test-v07:5001)[jinhailan]>EXPLAIN SELECT * FROM t1 INNER JOIN t2;
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------------+
    | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                 |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------------+
    |  1 | SIMPLE      | t1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | NULL                                  |
    |  1 | SIMPLE      | t2    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | Using join buffer (Block Nested Loop) |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------------+
    2 rows in set, 1 warning (0.00 sec)
    

      在连接查询的执行计划中,每个表都会对应一条记录,这些记录的id列的值是相同的,出现在前边的表表示驱动表,出现在后边的表表示被驱动表

    查询优化器可能对涉及子查询的查询语句进行重写,从而转换为连接查询

    Extra

    Using filesort:

    很多情况下排序操作无法使用到索引,只能在内存中(记录较少的时候)或者磁盘中(记录较多的时候)进行排序,设计MySQL的大叔把这种在内存中或者磁盘上进行排序的方式统称为文件排序(英文名:filesort

    Using temporary:去重,排序.

    执行许多包含DISTINCTGROUP BYUNION等子句的查询过程中,如果不能有效利用索引来完成查询,MySQL很有可能寻求通过建立内部的临时表来执行查询

    MySQL会在包含GROUP BY子句的查询中默认添加上ORDER BY子句

    不想为包含GROUP BY子句的查询进行排序,需要我们显式的写上ORDER BY NULL

    Start temporary, End temporary:先看一下自查询优化部分

    LooseScan:在将In子查询转为semi-join时,如果采用的是LooseScan执行策略,则在驱动表执行计划的Extra列就是显示LooseScan提示

    FirstMatch(tbl_name):在将In子查询转为semi-join时,如果采用的是FirstMatch执行策略,则在被驱动表执行计划的Extra列就是显示FirstMatch(tbl_name)提示

  • 相关阅读:
    推荐一个JavaScript触发器插件,可通过指定频次、指定时间内触发指定的处理函数
    TortoiseGit for windows安装与配置
    Postgresql 迁移随笔一
    三边定位 c#
    unset变量释放内存不起作用
    局域网下 连接别人的数据库授权
    iconv 参数详解
    urlencode()和rawurlencode()区别
    php数组函数
    php://input和parse_str()使用
  • 原文地址:https://www.cnblogs.com/asea123/p/12375878.html
Copyright © 2011-2022 走看看