mysql 执行路径 执行计划 慢查询

文章目录

  • mysql 执行路径
    • 系列文章
    • 查询执行的路径
      • 阶段一 mysql 客户端/服务端通信
      • 阶段二 查询缓存
      • 阶段三 查询解析,优化处理
        • 执行计划(重点)
          • 每个列的解释
            • 1. id
            • 2. select_type
            • 3. table
            • 4. type
            • 5. 其他列
            • 6. Extra
      • 阶段四 查询执行引擎
      • 阶段五 返回客户端
  • 如何定位慢sql
    • 查看慢查询日志参数
    • 慢查询日志分析工具
  • 参考

mysql 执行路径

系列文章

  • mysql 性能优化 | 第一篇 mysql B+Tree
  • mysql 性能优化 | 第二篇 MySql Myisam和innodb对比 索引优化建议
  • mysql 性能优化 | 第三篇 mysql存储引擎
  • mysql 性能优化 | 第四篇 mysql数据库的隔离级别
  • mysql 性能优化 | 第五篇 mysql 表锁 行锁
  • mysql 性能优化 | 第六篇 mysql MVCC Undo Redo
  • mysql 性能优化 | 第七篇 mysql 执行路径 执行计划 慢查询
  • mysql 性能优化 | 第八篇 mysql 配置优化

查询执行的路径

mysql 执行路径 执行计划 慢查询_第1张图片
mysql的执行路径大致分为5步

  1. mysql 客户端/服务端通信
  2. 查询缓存
  3. 查询解析,优化处理
  4. 查询执行引擎
  5. 返回客户端

阶段一 mysql 客户端/服务端通信

通信方式是"半双工"

  • 客户端可以发送数据给服务端,服务端也可以发送数据给客户端
  • 不能同时发送,客户端发送的时候,服务端必须等客户端发送完,反之亦然

mysql通信特点和限制

  • 客户端一旦开始发送消息,另一端要接收完整个消息才能响应
  • 客户端一旦开始接收数据没法停下来发送指令

mysql 客户端/服务端的通信-连接状态

对于一个mysql连接,或者说一个线程,时刻都有一个状态来标识这个连接正在做什么

查看命令

show full processlist;
show processlist

常见的状态

Sleep 线程正在等待客户端发送数据
Query 连接线程正在执行查询
Locked 现在正在等待表锁的释放
Sorting result 线程正在对结果进行排序
Sending data 向请求端返回数据

一般线程状态:全部请见官网

mysql官网一般线程状态

应用

通过show processlist命名查看线程的id/Time/info等信息
mysql 执行路径 执行计划 慢查询_第2张图片

  • time表示当前进程在这个状态的时间

  • info表示执行的sql

  • id可以找到执行很久的sql语句或者死锁的进程,通过kill id(进程号)可以关闭进程,mysql中的kill命令

阶段二 查询缓存

mysql缓存机制是默认关闭

工作原理

  1. 缓存select操作的结果集合sql语句

  2. 新的select语句,先查询缓存,判断是否存在可用的结果集

判断标准

与缓存的sql语句是否完全一样

show VARIABLES like 'query_cache%'

mysql 执行路径 执行计划 慢查询_第3张图片
默认关闭,如果要修改,只能修改my.cnf文件 query_cache_type=1

意义
1 开启,sql语句加上sql_no_cache可以使这条sql语句不使用缓存
0 关闭
2 按需开启,sql语句加上sql_cache可以使这条sql语句使用缓存

query_cache_limit表示单次查询结果大于这个值,就不会使用缓存

show status like 'Qcache%';

mysql 执行路径 执行计划 慢查询_第4张图片

参数值 意义
Qcache_hits 命中次数
Qcache_inserts 插入缓存次数

不会使用缓存的情况

  • 查询字段中含有函数
  • sql中使用sql_no_cache
  • sql返回结果超过单次最大限制
  • 查询不涉及表
  • 查询的是系统表

阶段三 查询解析,优化处理

  • 解析sql

    通过lex词法分析,yacc语法分析将sql语句解析成解析树

  • 预处理阶段

    根据mysql的语法规则进一步检查解析树的合法性,如检查数据的表和列是否存在,解析名字和别名的设置,进行权限的验证

  • 查询优化器

    优化器的主要作用就是找到最优的执行计划

    查询优化器如何找到最优的执行计划?

    • 基于成本计算的原则。尝试各种执行计划,随机读取一个4K的数据块进行分析

    • 使用等价变化规则

    • 将可转换的外连接转换成内连接

    • 优化count、min、max等函数

    • 覆盖索引扫描

    • 子查询优化

    • 提前终止查询

    • IN的优化(in的条件中的值会采用二分查找进行对比)

执行计划(重点)

explain select * from eval_leaders t where t.id = 100268;

在sql语句前加explain

或者点击数据库客户端工具中的解释按钮
mysql 执行路径 执行计划 慢查询_第5张图片

每个列的解释
1. id

select查询的序列号,表示执行的顺序

  • id相同,执行顺序由上而下
  • id不同,如果是子查询,id的序号会增大,id值越大优先级越高,越先被执行
  • id相同又不同两种情况同时存在,id如果相同可以认为是一组,从上往下执行;所有组中,id值越大,优先级越高,越先执行
  • id为null,最后执行;select_type类型为UNION RESULT类型
2. select_type

查询的类型,主要是用于区分普通查询、联合查询、子查询等等

类型 意义
SIMPLE 简单的select查询,查询中不包括或者union
PRIMARY 查询中包含子部分,最外层查询则被标记为primary
SUBQUERY 表示在select或者where列表中包含了子查询
MATERIALIZED where后面in条件的子查询
UNION 若第二个select出现在union之后,则被标记为union
UNION RESULT 从union表获取结果的select
3. table

查询涉及的表

直接显示表名或者别名

代码 意义
由ID为M,N查询union产生的结果
< subqueryN> 有ID为N查询产生的结果
4. type

访问类型,sql查询优化中一个很重要的指标,结果值从好到坏依次是

system>const>eq_ref>ref>range>index>ALL

代码 意义
system 表只有一行记录(等于系统表),const类型的特例,基本不会出现
const 通过索引依次就找到了,const用于比较primary key或者unique索引
eq_ref 唯一索引扫描,对应每个索引键,表中只有一条记录与之匹配。常见primary key或者unique索引
ref 非唯一性索引扫描,返回匹配某个单独值的所有行,本质是也是一种索引访问
range 只检索给定范围的行,使用一个索引来选择行
index Full Index Scan,索引全表扫描,把索引从头到尾扫一遍
ALL Full Table Scan,遍历全表以找到匹配行
5. 其他列
列名 意义
possible_keys 查询过程中有可能用到的索引
key 实际使用的索引,如果为null,则没有使用索引
rows 根据表统计信息或者索引选用情况,大致估算出找到所需的记录所需要读取的行数
filtered 返回结果的行占需要读到行(rows)的百分比,值越大越好
6. Extra

十分重要的额外信息

代码 意义
Using filesort mysql对数据使用一个外部文件内容进行排序,而不是按照表内的索引进行排序读取
Using temporary 使用临时表保存中间结果,也就是说mysql在对查询结果排序时使用临时表,常见于order by或者group by
Using index 表示相应的select操作中使用了覆盖索引(Covering Index),避免了访问表的数据行,效率高
Using where 使用了where过来条件
select tables optimized away 基于索引优化MIN/MAX操作或者Myisam存储引擎优化count(*)操作,不必等到执行阶段在进行计算,查询执行计划生成的阶段即可完成优化

阶段四 查询执行引擎

调用插件式的存储引擎得到原子API的功能进行执行计划的执行

阶段五 返回客户端

  • 有需要做缓存的,执行缓存操作
  • 增量的返回结果
    • 开始生产第一条结果时,mysql就开始往请求方逐步返回数据
    • 好处:mysql服务器无须保存过多的数据,浪费内存,用户体验好,马上就能拿到数据

如何定位慢sql

  • 业务驱动
  • 测试驱动
  • 慢查询日志

查看慢查询日志参数

show variables like 'slow_query_log%';

在这里插入图片描述
开启

set global slow_query_log = on;
set global slow_query_log_file = '/var/lib/mysql/mysql-slow.log';
#没有命中索引的记录到慢查询
set global log_queries_not_using_indexes = on;
#超过多少秒进入慢查询
set global long_query_time = 0.1;#(秒)

shell命令

vi  /var/lib/mysql/mysql-slow.log

或者是拷贝到本地用文本编辑器打开
mysql 执行路径 执行计划 慢查询_第6张图片

代码 意义
Time 日志记录的时间
User@Host 执行的用户及主机
Query_time 查询耗费时间 Lock_time 锁表时间 Rows_sent 发送给请求方的记录条数 Rows_examined 语句扫描的记录条数
SET timestamp 语句执行的时间点
select… 执行的具体语句

慢查询日志分析工具

  1. mysqldumpslow
    按query_timeo平均查询时间的顺序取出前10条的慢查询日志
    mysql 执行路径 执行计划 慢查询_第7张图片
mysqldumpslow -s at -t 10 /var/lib/mysql/mysql-slow.log
  1. mysqlsla

  2. pt-query-digest

参考

  1. 腾讯课堂-咕泡学院-seven老师-mysql性能优化
  2. mysql官网

你可能感兴趣的:(数据库,mysql,性能优化)