zoukankan      html  css  js  c++  java
  • Explain 索引优化分析

    Explain 语法

    # 语法
    explain + DQL语句
    
    mysql> explain select * from city where countrycode ='CHN' or countrycode ='USA';
    
    # 查询中国和美国的数据
    mysql> select * from city where countrycode ='CHN' or countrycode ='USA';
    mysql> select * from city where countrycode in ('CHN','USA');
    mysql> select * from city where countrycode = 'CHN' union all select * from city where countrycode = 'USA';
    
    # Explain 分析 SQL 
    mysql>  explain select * from city where countrycode ='CHN' or countrycode ='USA';
    +----+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------+
    | id | select_type | table | type  | possible_keys | key         | key_len | ref  | rows | Extra                 |
    +----+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------+
    |  1 | SIMPLE      | city  | range | CountryCode   | CountryCode | 3       | NULL |  637 | Using index condition |
    +----+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------+
    1 row in set (0.00 sec)
    

    ID,Table,Partitions 字段

    ID:查询顺序号

    Table:查询的表名

    Partitions:表所使用的分区,如果要统计十年公司订单的金额,可以把数据分为十个区,每一年代表一个区。这样可以大大的提高查询效率

    Select_type 字段

    select 查询的类型,主要是用于区别普通查询,联合查询,嵌套的复杂查询

    Name Description
    simple 简单的 select 查询,查询中不包含子查询或者 union
    primary 查询的 where 列表中若包含任何复杂的子查询,最外层查询则被标记为 primary
    subquery 在 select 或 where 列表中包含了子查询
    derived 在 from 后,where 之前中包含的子查询被标记为 derived(衍生)MySQL 会递归执行这些子查询,把结果放在临时表里。
    union 若第二个 select 出现在 union 之后,则被标记为 union,若 union 包含在 from 子句的子查询中,外层 select 将被标记为 derived
    union result 从 union 表获取结果的 select
    # simple:简单的select 查询,查询中不包含子查询或者 union
    
    # primary 和 subquery,最外层查询被标记为 primary,内层查询被标记为 subquery
    mysql> explain select name,countrycode,district,population from city where population=(select max(population) from city);
    +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
    +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    |  1 | PRIMARY     | city  | ALL  | NULL          | NULL | NULL    | NULL | 4188 | Using where |
    |  2 | SUBQUERY    | city  | ALL  | NULL          | NULL | NULL    | NULL | 4188 | NULL        |
    +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    2 rows in set (0.00 sec)
    
    
    
    # derived,根据 select 语句衍生出临时表 tmp_students 时出现
    mysql> select *  from (select *  from students_backup) tmp_tudents  where id=2;
    +----+------+-----+--------+---------------------+----------+-------+
    | id | name | age | gender | register_time       | hobby    | phone |
    +----+------+-----+--------+---------------------+----------+-------+
    |  2 | wzh  |  18 | M      | 2020-07-14 22:02:04 | wzhhobby | 12    |
    +----+------+-----+--------+---------------------+----------+-------+
    1 row in set (0.00 sec)
    
    mysql> explain select *  from (select *  from students_backup) tmp_tudents  where id=2;
    +----+-------------+-----------------+------+---------------+-------------+---------+-------+------+-------+
    | id | select_type | table           | type | possible_keys | key         | key_len | ref   | rows | Extra |
    +----+-------------+-----------------+------+---------------+-------------+---------+-------+------+-------+
    |  1 | PRIMARY     | <derived2>      | ref  | <auto_key0>   | <auto_key0> | 4       | const |    0 | NULL  |
    |  2 | DERIVED     | students_backup | ALL  | NULL          | NULL        | NULL    | NULL  |    7 | NULL  |
    +----+-------------+-----------------+------+---------------+-------------+---------+-------+------+-------+
    2 rows in set (0.00 sec)
    
    
    
    
    # union  和  union result,连表查询时出现
    mysql> explain select * from students where id> 3 union select * from students_backup where id >3;
    +----+--------------+-----------------+-------+---------------+---------+---------+------+------+-----------------+
    | id | select_type  | table           | type  | possible_keys | key     | key_len | ref  | rows | Extra           |
    +----+--------------+-----------------+-------+---------------+---------+---------+------+------+-----------------+
    |  1 | PRIMARY      | students        | range | PRIMARY       | PRIMARY | 4       | NULL |    4 | Using where     |
    |  2 | UNION        | students_backup | range | PRIMARY       | PRIMARY | 4       | NULL |    4 | Using where     |
    | NULL | UNION RESULT | <union1,2>      | ALL   | NULL          | NULL    | NULL    | NULL | NULL | Using temporary |
    +----+--------------+-----------------+-------+---------------+---------+---------+------+------+-----------------+
    3 rows in set (0.00 sec)
    

    Possible_keys 字段

    显示查询语句可能用到的索引,一个或多个,或为 NULL,不一定被查询实际使用,仅供参考使用

    Key 字段

    显示查询语句实际使用的索引,若为 NULL,则表示没有使用索引

    Key_len 字段

    显示索引中使用的字节数,可通过key_len计算查询中使用的索引长度。在不损失精确性的情况下索引长度越短越好

    Ref 字段

    显示索引的哪一列或常量被用于查找索引列上的值

    Rows 字段

    根据表统计信息及索引选用情况,估算出找到所需的记录所需要读取的行数,并不是查询结果的行数,值越大越不好

    Type 字段

    # index:扫描全部索引
    mysql> ALTER TABLE city ADD INDEX(name);
    mysql> explain select Name from city;
    
    # range:范围查询
    mysql> explain select * from city where countrycode ='CHN' or countrycode ='USA';
    #有限制查询到的数据在总数据的 15% 以内,超过则为全文扫描,在查询可以使用 limit 限制在 15% 以内
    mysql> explain select * from city where countrycode != 'CHN' limit 500;
    
    # ref:精确查询
    	mysql> explain select * from city where countrycode ='CHN';
    
    # eq_ref:使用多表联查时会出现
    mysql> create table students_backup like students;
    mysql> insert into students_backup select * from students;
    mysql> explain select * from students,students_backup student  where student.id=students.id and student.id > 5;
    +----+-------------+----------+--------+---------------+---------+---------+------------------+------+-------------+
    | id | select_type | table    | type   | possible_keys | key     | key_len | ref              | rows | Extra       |
    +----+-------------+----------+--------+---------------+---------+---------+------------------+------+-------------+
    |  1 | SIMPLE      | students | range  | PRIMARY       | PRIMARY | 4       | NULL             |    2 | Using where |
    |  1 | SIMPLE      | student  | eq_ref | PRIMARY       | PRIMARY | 4       | mydb.students.id |    1 | NULL        |
    +----+-------------+----------+--------+---------------+---------+---------+------------------+------+-------------+
    
    # const:查询的条件,是主键索引或者唯一键索引
    mysql> explain select * from city where id=1;
    
    # system:查询级别与 const 相同,当数据很少时出现
    
    
    # null:不需要读取数据,只需要获取最大值或者最小值
    mysql> explain select max(population) from city;
    

    Extra 字段

    Name Description
    Using filesort 说明MySQL会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为“文件排序” 。出现这个就要立刻优化sql。
    Using temporary 使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序 order by 和 分组查询 group by。 出现这个更要立刻优化sql。
    Using index 表示相应的 select 操作中使用了覆盖索引(Covering index),避免访问了表的数据行,效果不错!如果同时出现Using where,表明索引被用来执行索引键值的查找。如果没有同时出现Using where,表示索引用来读取数据而非执行查找动作。
    Covering Index 覆盖索引,也叫索引覆盖,就是select 的数据列只用从索引中就能够取得,不必读取数据行,MySQL可以利用索引返回select 列表中的字段,而不必根据索引再次读取数据文件。只需要在一棵索引树上就能获取SQL所需的所有列数据,无需回表
    Using index condition 在 MySQL5.6 版本后加入的新特性,优化器会在索引存在的情况下,通过符合RANGE范围的条数 和 总数的比例来选择是使用索引还是进行全表遍历。
    Using join buffer 表明使用了连接缓存
    impossible where where 语句的值总是false,不可用,不能用来获取任何元素
    distinct 优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作
    Using where 表明使用了 where 过滤
  • 相关阅读:
    双日历时间段选择控件—daterangepicker(汉化版)
    vue elementui table表格展开行每次只展开一行
    vue-pdf PDF文件预览
    async await
    vuex发送axios请求
    jq调用浏览器下载文件 window.open()
    禁止页面右键、选择、F12操作
    vue 点击一条消息跳转相应的页面且对应相应的大模块和办理状态
    vue-infinite-scroll 滚动加载下一页
    填写流程当前登录人可以填写除自己可填项外还可看到他前面经办人相关填写的内容,且经办人后面的不可见
  • 原文地址:https://www.cnblogs.com/zzzwqh/p/13332853.html
Copyright © 2011-2022 走看看