在上一篇文章《用Explain 命令分析 MySQL 的 SQL 执行》中,我们讲解了 Explain 命令的详细使用。但是它只能展示 SQL 语句的执行计划,无法展示为什么一些其他的执行计划未被选择,比如说明明有索引,但是为什么查询时未使用索引等。为此,MySQL 提供了 Optimizer Trace 功能,让我们能更加详细的了解 SQL 语句执行的所有分析,优化和选择过程。

如果您想更深入地了解为什么选择某个查询计划,那么优化器跟踪非常有用。虽然 EXPLAIN 显示选定的计划,但Optimizer Trace 能显示为什么选择计划:您将能够看到替代计划,估计成本以及做出的决策。本篇文章会详细讲解 Optimizer Trace 展示的所有相关信息,并且会辅之一些具体使用案例。

基于成本的执行计划

在了解 Optimizer Trace 的之前,我们先来学习一下 MySQL 是如何选择众多执行计划的。

MySQL 会使用一个基于成本(cost)的优化器对执行计划进行选择。每个执行计划的成本大致反应了该计划查询所需要的资源,主要因素是计算查询时将要访问的行数。优化器主要根据从存储引擎获取数据的统计数据和数据字典中元数据信息来做出判断。它会决定是使用全表扫描或者使用某一个索引进行扫描,也会决定表 join的顺序。优化器的作用如下图所示。

优化器会为每个操作标上成本,这些成本的基准单位或最小值是从磁盘读取随机数据页的成本,其他操作的成本都是它的倍数。所以优化器可以根据每个执行计划的所有操作为其计算出总的成本,然后从众多执行计划中,选取成本最小的来最终执行。

既然是基于统计数据来进行标记成本,就总会有样本无法正确反映整体的情况,这也是 MySQL 优化器有时做出错误优化的重要原因之一。

Optimizer Trace 的基本使用

首先,我们来看一下具体如何使用 Optimizer Trace。默认情况下,该功能是关闭的,大家可以使用如下方式打开该功能,然后执行自己需要分析的 SQL 语句,然后再从 INFORMATIONSCHEMA 的 OPTIMIZERTRACE中查找到该 SQL 语句执行优化的相关信息。

# 1. 打开optimizer trace功能 (默认情况下它是关闭的):
SET optimizer_trace="enabled=on";
SELECT ...; # 这里输入你自己的查询语句
SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
# 当你停止查看语句的优化过程时,把optimizer trace功能关闭
SET optimizer_trace="enabled=off";

这个 OPTIMIZER_TRACE 表有4个列,如下所示:

  • QUERY:表示我们的查询语句。

  • TRACE:表示优化过程的JSON格式文本。

  • MISSING_BYTES_BEYOND_MAX_MEM_SIZE:由于优化过程可能会输出很多,如果超过某个限制时,多余的文本将不会被显示,这个字段展示了被忽略的文本字节数。

  • INSUFFICIENT_PRIVILEGES:表示是否没有权限查看优化过程,默认值是0,只有某些特殊情况下才会是 1,我们暂时不关心这个字段的值。

其中,信息最多也最为重要的就是第二列 TRACE,它也是我们后续分析的重点。

TRACE 列的基本格式

TRACE 列的内容是一个超级大的 JSON 数据,直接展开然后一条一条解析估计能看到大伙脑壳疼。

所以,我们先来看一下这坨大 JSON 的骨架。它有三大块内容,也代表着 SQL 语句处理的三个阶段,分别为准备阶段,优化阶段和执行阶段。

接下来,我们详细介绍一个案例,在案例中介绍涉及到的具体字段和含义。

为什么查询未走索引而是全表扫描

首先,SQL 语句查询不使用索引的情况有很多,我们这里只讨论因为基于成本的优化器认为全表查询执行计划的成本低于走索引执行计划的情况。

如下图这个场景,明明 val 列上有索引,并且 val 现存值也有一定差异性,为什么没有使用索引进行查询呢?

我们按照上文使用 Optimizer Trace 找到其 joinoptimization 中 rangeanalysis 相关数据,它会展示 where 从句范围查询过程中索引的选择情况

由上图可以看出,MySQL 对比了全表扫描和使用 val 作为索引两个方案的成本,最后发现虽然全表扫描需要扫描更多的行,但是成本更低。所以选择了全表扫描的执行方案。

这是为什么呢?明明使用 val 索引可以少扫描 4 行。这其实涉及 InnoDB 中使用索引查询数据行的原理。

Innodb引擎查询记录时在无法使用索引覆盖(也就是需要查询的数据多与索引值,比如该例子中,我要查name,而索引列是 val)的场景下,需要做回表操作获取记录的所需字段,也就是说,通过索引查出主键,再去查数据行,取出对应的列,这样势必是会多花费成本的。

所以在回表数据量比较大时,经常会出现 Mysql 对回表操作查询代价预估代价过大而导致不使用索引的情况。

一般来说,当SQL 语句查询超过表中超过大概五分之一的记录且不能使用覆盖索引时,会出现索引的回表代价太大而选择全表扫描的现象。且这个比例随着单行记录的字节大小的增加而略微增大。

通过 range_analysis 中的相关数据也可以对 where 从句使用多个索引列,如何选择执行时使用的索引的情况进行分析。

小节

终于,介绍了有关于 MySQL 语句执行分析的 explain 和 Optimizer Trace,下一篇,我们将分析具体的死锁场景。

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:

长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

100% 展示 MySQL 语句执行的神器-Optimizer Trace相关推荐

  1. mysql trace工具_100% 展示 MySQL 语句执行的神器-Optimizer Trace

    在上一篇文章<用Explain 命令分析 MySQL 的 SQL 执行>中,我们讲解了 Explain 命令的详细使用.但是它只能展示 SQL 语句的执行计划,无法展示为什么一些其他的执行 ...

  2. MySQL语句执行过程

    目录 前言 MySQL语句执行过程 一.连接器 二.查询缓存 三.分析器 四.优化器 1.逻辑查询优化 1.1 逻辑查询优化思路. 2.2 查询重写规则 2.3 启发式规则再逻辑优化阶段的应用 2.3 ...

  3. hive 把mysql语句执行_Hive SQL 语句的执行顺序

    提示 Hive SQL 教程 编写中,使用过程中有任何建议,提供意见.建议.纠错.催更加微信 sinbam. 当我们写了一个 sql,但是执行起来很慢,这时如果我们知道这个sql的底层执行流程是怎样的 ...

  4. mysql一条语句是如何被执行的——带你了解mysql语句执行内部顺序

    文章目录 写在前面 MySQL基本架构 超详细架构图 连接器 查询缓存 解析器 MySQL 8.0对Parser所做的改进 优化器 执行器 存储引擎 SQL语句执行时间分析 参考资料 写在前面 sel ...

  5. Mysql语句执行逻辑

    Mysql基础知识 我们要了解mysql,那就从最常见的流程开始,我们在cilent端输入一条sql,究竟会经历哪些步骤? 可以思考30s - 一条SQL查询语句执行流程 select * from ...

  6. DBA大牛告诉你,如何让MySQL语句执行加速?

    一打开科技类论坛,最常看到的文章主题就是MySQL性能优化了,为什么要优化呢? 因为: •数据库出现瓶颈,系统的吞吐量出现访问速度慢 •随着应用程序的运行,数据库的中的数据会越来越多,处理时间变长 • ...

  7. 获取Mysql语句执行时的详细信息

    1. 通过SHOW STATUS获取更多信息 在调试mysql语句时,如果执行计划不能提供足够的信息支持判断,可以通过在语句执行前执行FLUSH STATUS,执行完语句后执行SHOW STATUS ...

  8. 如何让MySQL语句执行加速

    like 前导符优化 like模糊查询形如'%AAA%'和'%AAA'将不会使用索引,但是业务上不可避免可能又需要使用到这种形式. 通常的方法有两种: 方案一:使用覆盖索引,即查询出的列只是用索引就可 ...

  9. hive 把mysql语句执行_R分别连接mysql hive执行操作

    大半年忘记更新工作记录了,惭愧,慢慢补上. mysql/hive 是两类常用的不同类型的数据库,在数据操作上存在一定的区别. 1-MYSQL的连接. ​library(DBI) library(RMy ...

最新文章

  1. 正则表达式,以前总结的,大不分来择自网上
  2. Illegal access:this web application instance has been stopped already
  3. poj 2362(剪枝)
  4. c#与mysql数据库连接以及.net framework版本修改问题
  5. UBUNTU下彻底删除MYSQL
  6. 开关 关闭_无论用什么品牌手机,这个开关要关闭,以免耗电又卡顿,抓紧试试...
  7. 万法归宗之Hadoop编程无界限
  8. 最简便的Revit信息导出到数据库本地SQL SERVER
  9. Ubuntu快捷方式的描述
  10. 实验4 数据库的连接查询
  11. -个很个性的二本人计时
  12. web前端三大主流框架分析对比
  13. oracle pdb启动日志,案例:Oracle 12C 数据库pdb丢失数据文件后的完整恢复过程
  14. 黑盒测试和白盒测试的区别
  15. PHP-FPM(PHP进程管理器)
  16. mysql 章节作业题
  17. 基于ArUco的视觉定位(一)
  18. 我的世界java笔刷指令_原版创世神刷子工具命令方块指令分享
  19. 【九度OJ】查找第K小数
  20. 这可是全网EVE安装最完整,最详细的图解,没有之一【安装图解】

热门文章

  1. 嵌入式自学多久可以找工作?应届生找嵌入式工作难吗?
  2. java无刷新上传图片_【java实现web文件无刷新上传】
  3. poj1679(次小生成树)
  4. [kuangbin带你飞]专题六-生成最小树
  5. [蓝桥杯2016初赛]卡片换位 bfs+set
  6. 蓝桥杯第九届决赛-交换次数-java
  7. P1583 魔法照片
  8. python 重载_python模块重载的五种方法
  9. 实施自动化测试的六个目标和意义
  10. 为什么当项目启动后执行两次过滤器 再进行访问资源时执行一次过滤器