MySQL 性能分析大杀器(第一章)

今天让我们了解下 MySQL 性能分析大杀器 —— explain

使用 explain 可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 怎么处理你的 SQL 语句的,分析你的查询语句和表结构的性能瓶颈。

如何使用 explain

使用方式,直接在 sql 语句前加上 explain 即可。例如,如下:

explain select * from users;

-- 本意为显示警告信息。但是和 explain 一块儿使用,就会显示出优化后的 sql。需要注意使用顺序。(两条 sql 需要放在一起同时执行,因此 explain 后面一定要加分号 `;`)
show warnings;

explain 能够干什么

  • 读取表的顺序
  • 哪些索引能够被使用
  • 数据读取操作的操作类型
  • 哪些索引能够被实际使用
  • 表之间的引用
  • 每张表有多少行被物理查询

具体的字段解读

使用 explain 之后,会返回如下各种信息。其中最重要的 5 个字段是:id、type、key、rows、Extra

那么我们依次详细解释每个字段的含义:

  • id:select 查询的序列号,包含一组数字,表示查询中执行 select 子句或操作表的顺序。

会出现如下三种可能:

  1. id 相同,则表示执行顺序由上至下。
  2. id 不同,如果是子查询,则表示 id 的序号会递增。id 值越大优先级越高,越先被执行。
  3. id 有相同也有不同的,id 值越大优先级越高越先被执行,id 值相同的按由上到下执行。

  • select_type:查询的类型,主要是用于区别普通查询联合查询子查询等的复杂查询

大致会有如下几种结果:

  1. simple :简单的 select 查询,查询中不包含子查询或者 union 语句。
  2. primary :查询中若包含任何复杂的子查询部份,那么最外层查询则被标记为 primary
  3. subquery :在 select 或 where 列表中包含子查询语句。
  4. derived :在 from 列表中包含的子查询被标记为 derived(衍生)MySQL 会递归执行这些子查询,把结果放在临时表里。
  5. union :若第二个 select 出现在 union 之后,则被标记为 union,若 union 包含在 from 子句的子查询中,外层 select 将被标记为 derived
  6. union result :从 union 表获取结果的 select

  • table :显示这一行的数据是关于哪张表的

  • type :访问类型排序
    • 常用的从最好到最差依次是,system > const > eq_ref > ref > range > index > ALL
    • 完整的从最好到最差依次是 system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > ALL
    • 一般来说, 得保证查询至少达到 range 级别,最好能达到 ref 级别

下面是 type 字段可能出现的一些值。

  1. system :表只有一行记录(等于系统表),这是 const 类型的特例,平时不会出现,这个也可以忽略不计。
  2. const :表示通过索引一次就找到了,const 用于比较 primary key 或者 unique 索引。因为只匹配一行数据,所以很快。如将主键置于 where 列表中,MySQL 就能将该查询转换为一个常量
  3. eq_ref : 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。
  4. ref :非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。
  5. range :只检索给定范围的行,使用一个索引来选择行,key 列显示使用了哪个索引,一般就是在你的 where 语句中出现了 between 、< 、> 、in 等的查询。这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而结束于另一点,不用扫描全部索引
  6. index :Full Index Scan,Index 与 ALL 区别为 index 类型只遍历索引树。这通常比 ALL 快,因为索引文件通常比数据文件小。(也就是说虽然 all 和 index 都是读全表,但 index 是从索引中读取的,而 all 是从硬盘中读的)
  7. all :Full Table Scan,将遍历全表以找到匹配的行

一般来说,得保证查询至少达到 range 级别,最好能达到 ref


  • possible_keys :显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用 这一点尤其要注意。

  • key :实际使用的索引。如果为 null,则没有使用索引。查询中若使用了覆盖索引,则该索引仅出现在 key 列表中。

  • key_len : 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好。key_len 显示的值为索引字段的最大可能长度,并非实际使用长度,即 key_len 是根据表定义计算而得,不是通过表内检索出的

  • ref :显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值

  • rows :根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数(行数越小越好)

  • Extra :包含不适合在其它列中显示但十分重要的额外信息

下面是一些 Extra 可能会出现的一些值。

  1. Using filesort :说明 mysql 会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL 中无法利用索引完成的排序操作称为“文件排序”。九死一生了,效率比较差
  2. Using temporary :使用了临时表保存中间结果,MySQL 在对查询结果排序时使用临时表。常用于排序 order by 和分组查询 group by。可以说得上就是 十死无生,效率最差!
  3. Using index :表示相应的 select 操作中使用了覆盖索引(Covering index),避免访问了表的数据行,效率不错!如果同时出现 using where ,表明索引被用来执行索引键值的查找;如果没有同时出现 using where ,表明索引用来读取数据而非执行查找动作。
  4. Using where :表明使用了 where 过滤
  5. using join buffer :使用了连接缓存
  6. impossible where :where 子句的值总是 false,不能用来获取任何元组
  7. select tables optimized away :在没有 group by 子句的情况下,基于索引优化 min/max 操作或者对于 MyISAM 存储引擎优化 count(*) 操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
  8. distinct :优化 distinct 操作,在找到第一匹配的元组后即停止找同样值的动作

好了,今天的分享就到这里了,下一篇会继续介绍其他的检测 MySQL 效率的方式,敬请期待。


最后说个事
公号算法变了,为防止看不到我的更新
大家帮忙加个星标
点击上方的公众号卡片
再点右上角三个点
就能看到设为星标
算我跪下来求你们

作者简介:

95后某跨境电商企业程序猿,白天搬砖码代码,晚上自媒体写文章,持续更新编程、科技、互联网相关文章,偶尔也会无痛呻吟,感慨人生百态。自己淋过雨,所以也想为别人撑撑伞。

往期精选:

微信上的这3个隐藏“标志”,代表有人喜欢你,一眼便知

微信,看看你的另一半跟谁聊天频繁!

微信上已删除的聊天记录,用这几种方式就可以恢复啦!

让你的微信“拍一拍”有趣且不失风度

微信年度账单来了,不敢看!

还在使用默认的微信图标?赶紧换个吧!

我的微信和你们的不一样!?

原文始发于微信公众号(浅墨觅尘往):MySQL 性能分析大杀器(第一章)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/222111.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!