MySQL查询性能优化七种武器之链路追踪

MySQL优化器可以生成Explain执行计划,我们可以通过执行计划查看是否使用了索引,使用了哪种索引?

但我们并不确切地知道为什么使用这个索引。

[En]

But we don’t know exactly why this index is used.

好在MySQL提供了一个好用的工具 — optimizer trace(优化器追踪),可以帮助我们查看优化器生成执行计划的整个过程,以及做出的各种决策,包括访问表的方法、各种开销计算、各种转换等。

1. 查看optimizer trace配置

show variables like '%optimizer_trace%';

MySQL查询性能优化七种武器之链路追踪

输出参数详解:

optimizer_trace 主配置,enabled的on表示开启,off表示关闭,one_line表示是否展示成一行
optimizer_trace_features 表示优化器的可选特性,包括贪心搜索、范围优化等
optimizer_trace_limit 表示优化器追踪最大显示数目,默认是1条
optimizer_trace_max_mem_size 表示优化器追踪占用的最大容量
optimizer_trace_offset 表示显示的第一个优化器追踪的偏移量

2. 开启optimizer trace

optimizer trace默认是关闭,我们可以使用命令手动开启:

SET optimizer_trace="enabled=on";

MySQL查询性能优化七种武器之链路追踪

3. 线上问题复现

首先创建一些要备份的数据,然后创建一个用户表:

[En]

First create some data for backup, and create a user table:

CREATE TABLE user (
  id int NOT NULL AUTO_INCREMENT COMMENT '主键',
  name varchar(100) NOT NULL COMMENT '姓名',
  gender tinyint NOT NULL COMMENT '性别',
  PRIMARY KEY (id),
  KEY idx_name (name),
  KEY idx_gender_name (gender,name)
) ENGINE=InnoDB COMMENT='用户表';

创建了两个索引,分别是(name)和(gender, name)。

执行一条SQL,看到底用到了哪个索引:

select * from user where gender=0 and name='一灯';

MySQL查询性能优化七种武器之链路追踪

跟期望的一致,优先使用了(gender, name)的联合索引,因为where条件中刚好有 gendername两个字段。

我们把这条SQL传参换一下试试:

select * from user where gender=0 and name='张三';

MySQL查询性能优化七种武器之链路追踪

这次竟然用了(name)上面的索引,同一条SQL因为传参不同,而使用了不同的索引。

到这里,使用现有工具,我们已经无法排查分析,MySQL优化器为什么使用了(name)上的索引,而没有使用(gender, name)上的联合索引。

只能请今天的主角 —optimizer trace(优化器追踪)出场了。

3. 使用optimizer trace

使用 optimizer trace查看优化器的选择过程:

SELECT * FROM information_schema.OPTIMIZER_TRACE;

MySQL查询性能优化七种武器之链路追踪

输出结果共有4列:

QUERY 表示我们执行的查询语句
TRACE 优化器生成执行计划的过程(重点关注)
MISSING_BYTES_BEYOND_MAX_MEM_SIZE 优化过程其余的信息会被显示在这一列
INSUFFICIENT_PRIVILEGES 表示是否有权限查看优化过程,0是,1否

接下来我们看一下 TRACE列的内容,里面的数据很多,我们重点分析一下 range_scan_alternatives结果列,这个结果列展示了索引选择的过程。

MySQL查询性能优化七种武器之链路追踪

输出结果字段含义:

index 索引名称
ranges 查询范围
index_dives_for_eq_ranges 是否用到索引潜水的优化逻辑
rowid_ordered 是否按主键排序
using_mrr 是否使用mrr
index_only 是否使用了覆盖索引
in_memory 使用内存大小
rows 预估扫描行数
cost 预估成本大小,值越小越好
chosen 是否被选择
cause 没有被选择的原因,cost表示成本过高

从输出结果中,可以看到优化器最终选择了使用(name)索引,而(gender, name)索引因为成本过高没有被使用。

再也不用担心找不到MySQL用错索引的原因,赶紧用起来吧!

文章持续更新,可以微信搜一搜「 一灯架构 」第一时间阅读更多技术干货。

MySQL查询性能优化七种武器之链路追踪

Original: https://www.cnblogs.com/yidengjiagou/p/16594161.html
Author: 一灯架构
Title: MySQL查询性能优化七种武器之链路追踪

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/505004/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • gitlab-runner浅谈——【git fetch-pack: expected shallow list】解决方法

    配置完gitlab-runner后执行job总是失败,如下: 解决方法 分析原因发现是git的版本太低了,我用的是系统自带的1.8.3的版本。后来更新为:2.31.1 后job可以…

    数据库 2023年6月11日
    0110
  • 阻塞非阻塞和同步异步的区分 参考一些书籍

    编程中一直对这两个概念不是很理解,在网上搜了很多资料大概描述的其实都很模糊,有时候还自相矛盾,很容易搞混,这里说一下我对这两个概念的理解。首先看一下相关技术书籍对这两个概念的描述,…

    数据库 2023年6月16日
    0261
  • JDK自带线程池学习

    JDK自带线程池 线程池的状态 线程有如下状态 RUNNING状态:Accept new tasks and process queued tasks SHUTDOWN状态:Don…

    数据库 2023年6月11日
    0138
  • 十一章 配置文件参数化

    把Spring配置文件中需要经常修改的字符串信息,转移到一个更小的配置文件中 1. 小配置文件(.properties) 2. 好处 : 利于维护 1.配置文件参数化开发步骤 已数…

    数据库 2023年6月14日
    098
  • Mysql客户端的安装

    Mysql数据库(简称)属于C/S架构,正常工作中一般都会提供服务端,我们只需要安装客户端进行查询修改数据等操作即可。 在正常工作中,无论是测试人员还是开发人员,总数据库管理员(测…

    数据库 2023年5月24日
    0142
  • Java的值传递

    1. 形参和实参 实参(实际参数) :用于传递给函数/方法的参数,必须有确定的值。 形参(形式参数) :用于定义函数/方法,接收实参,不需要有确定的值 2. 值传递和引用传递 值传…

    数据库 2023年6月14日
    095
  • 4_爬NMPA药监总局_动态加载_传ID

    http://scxk.nmpa.gov.cn:81/xk/ import requests url = ‘http://scxk.nmpa.gov.cn:81/xk/itowne…

    数据库 2023年6月11日
    0114
  • SQL优化

    一、插入优化 批量插入 insert into tb_name values (1,"张三"),(2,"张三"),(3,"张三&q…

    数据库 2023年5月24日
    0109
  • MySQL启动过程详解四:crash recovery

    当 MySQL关闭后,重启MySQL时,会进行 crash recovery操作,这里分析一下MySQL是如何进行的: 首先在启动Innodb存储引擎时会回滚事务系统的事务列表中未…

    数据库 2023年6月9日
    0115
  • 数据结构与算法-农夫过河问题

    农夫过河问题——最短路径算法 问题描述:农夫用小木筏将狼、羊、菜从起始岸运到目标岸,小木筏每次只能带一种物品,也可以什么都不带,因为食物链的关系,人不在的时候,狼会吃羊,羊会吃菜,…

    数据库 2023年6月14日
    0149
  • MySQL高可用架构-MMM、MHA、MGR、PXC、分库分表(补总结)

    404. 抱歉,您访问的资源不存在。 可能是URL不正确,或者对应的内容已经被删除,或者处于隐私状态。 [En] It may be that the URL is incorre…

    数据库 2023年5月24日
    0139
  • 细数线程池五大坑,一不小心线上就崩了

    系统性能优化的几种常用手段是异步和缓存。因此我们常常使用线程池异步处理一些业务。 线程池的使用还是相对比较简单的,首先创建一个线程池,然后通过execute或submit执行任务。…

    数据库 2023年6月6日
    0185
  • Centos7环境使用Mysql离线安装包安装Mysql5.7

    服务器环境:centos7 x64 需要安装:mysql5.7+ 1)检查mysql组合用户是否存在 2)若不存在,则创建mysql组和用户 版本选择,可以选择以下两种方式: 1)…

    数据库 2023年6月14日
    0107
  • MySQL主从备库过滤参数分析和测试

    测试环境: GTID的主从复制,主库(9900)——》备库(9909),存在测试库表: 9900_db1库:t1、t2、t3、t4、t5表 9900_db2库:t6、t7、t8、t…

    数据库 2023年5月24日
    096
  • 模板语法之传值取值

    模板语法之传值 变量相关使用:{{}}逻辑语法相关:{% %} 后端传值部分: def index(request): # 模版&amp…

    数据库 2023年6月14日
    097
  • Python–反射

    反射是一个很重要的概念,它可以把字符串映射到实例的变量或者实例的方法然后可以去执行调用、修改等操作。它有四个重要的方法: 1、getattr 获取指定字符串名称的对象属性 2、se…

    数据库 2023年6月9日
    090
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球