Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL

    • MySQL8一键安装配置优化
    • MySQL导出CSV格式解决乱码
    • MySQL 角色管理
    • MySQL网络抓包审计
    • MySQL性能压测
    • MySQL配合Consul读写分离
    • Gh-ost重建表,清除表碎片率
    • MySQL MGR配合MySQL-router实现innodb-cluster
    • MySQL 快速分析binlog定位问题
    • MySQL执行计划分析
      • MySQL执行计划分析
        • 使用 EXPLAIN 命令
        • 执行计划的各个字段解释
        • 关键访问类型详解
        • 优化建议
        • 实际案例分析
    • DBA常用SQL和命令整理备查
    • mysqldump实时同步数据
    • MySQL的事务隔离级别
    • MySQL存储过程批量生成数据
    • MySQL insert on duplicate key update,replace into , insert ignore的理解
    • MySQL不同字符集之间的区别和选择
    • MySQL为什么有时候会选错索引
    • MySQL死锁问题
    • MySQL使用SQL语句查重去重
    • MySQLdump逻辑备份
    • MySQL主从跳过异常GITD
    • MySQL8设置slowlog记录所有语句
    • MySQL8快速克隆插件使用指南
    • MySQL8双1设置保障安全
    • MySQL锁
    • innodb cluster安装
    • MySQL里的left join 和right join以及inner join
    • optimize table和 analyze table的区别
    • MySQL 字段的区分度计算公式
    • MySQLReplicaSet 安装
    • 脚本实现MySQL ReplicaSet 高可用
    • MySQL 的Left join,Right join和Inner join 的区别
    • MySQL45讲学习笔记
  • Redis

  • Keydb

  • TiDB

  • MongoDB

  • Elasticsearch

  • Kafka

  • victoriametrics

  • BigData

  • Sqlserver

  • 数据库
  • MySQL
Carry の Blog
2022-03-10
目录

MySQL执行计划分析

# MySQL执行计划分析

在数据库性能优化中,分析和理解SQL语句的执行计划是非常重要的一步。MySQL 提供了 EXPLAIN 语句来查看查询的执行计划。通过 EXPLAIN,我们可以了解查询是如何执行的,并找出可能的性能瓶颈。

# 使用 EXPLAIN 命令

你可以通过在查询前加上 EXPLAIN 关键字来查看执行计划。例如:

EXPLAIN SELECT * FROM users WHERE id = 1;
1

# 执行计划的各个字段解释

执行计划返回的结果包含多个字段,每个字段都有其特定的含义。以下是常见字段的解释:

  1. id:查询的序列号,表示查询中执行 select 子句或操作表的顺序。
    • id相同时,执行顺序由上至下
    • id不同时,id值越大优先级越高,越先执行
  2. select_type:查询的类型,常见的有:
    • SIMPLE:简单的 SELECT 查询,不包含子查询或 UNION
    • PRIMARY:最外层的 SELECT
    • SUBQUERY:子查询中的第一个 SELECT
    • DERIVED:派生表(在FROM子句中的子查询)
    • UNION:UNION中第二个及后面的SELECT语句
    • UNION RESULT:UNION的结果
  3. table:当前查询操作的表名或别名。
  4. partitions:匹配的分区信息(如果查询是基于分区表)。
  5. type:访问类型,表示MySQL如何查找表中的行,性能从好到差依次是:
    • system:表只有一行记录
    • const:通过索引一次就找到了,用于主键或唯一索引查询
    • eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配
    • ref:非唯一性索引扫描,返回匹配某个单独值的所有行
    • range:只检索给定范围的行,使用一个索引来选择行
    • index:全索引扫描,遍历整个索引树
    • ALL:全表扫描,MySQL遍历全表来找到匹配的行
  6. possible_keys:查询可能使用的索引。
  7. key:实际使用的索引。如果为NULL,则没有使用索引。
  8. key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好。
  9. ref:显示索引的哪一列被使用了。
  10. rows:MySQL认为必须检查的行数(估算值)。
  11. filtered:表示返回结果的行数占需读取行数的百分比。
  12. Extra:包含不适合在其他列中显示但十分重要的额外信息:
    • Using index:使用覆盖索引
    • Using where:使用WHERE过滤
    • Using temporary:使用临时表
    • Using filesort:需要额外的排序操作
    • Using join buffer:使用连接缓冲
    • Impossible WHERE:WHERE子句永远为false

# 关键访问类型详解

访问类型(type字段)是执行计划中最重要的指标之一,它显示了MySQL如何查找所需数据。按照性能从好到差的顺序:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
1

主要类型说明:

  1. system/const:

    • system:表中只有一行数据
    • const:基于主键或唯一索引的等值查询
  2. eq_ref:

    • 出现在多表连接中
    • 使用主键或唯一非空索引关联
  3. ref:

    • 使用非唯一索引或唯一索引的前缀匹配
    • 返回匹配某个单独值的记录行
  4. range:

    • 索引范围扫描
    • 常见于 <、>、BETWEEN、IN、LIKE 等操作
  5. index:

    • 全索引扫描
    • 相比ALL快,因为索引文件通常比数据文件小
  6. ALL:

    • 全表扫描
    • 性能最差,应尽量避免

# 优化建议

  1. 索引优化:

    • 在WHERE和JOIN条件中的列上建立适当的索引
    • 考虑使用复合索引,注意索引列的顺序
    • 避免过多索引,可能影响更新性能
  2. 查询优化:

    • 只查询需要的列,避免SELECT *
    • 使用LIMIT限制结果集大小
    • 避免使用SELECT DISTINCT,考虑用其他方式替代
  3. 表结构优化:

    • 选择合适的数据类型,尽量使用较小的数据类型
    • 适当分表分库,控制单表数据量
  4. 监控与维护:

    • 定期分析慢查询日志
    • 使用ANALYZE TABLE更新统计信息
    • 合理设置long_query_time参数

# 实际案例分析

考虑以下查询:

EXPLAIN SELECT * FROM orders o 
JOIN users u ON o.user_id = u.id 
WHERE o.order_date >= '2023-01-01' 
  AND o.status = 'completed';
1
2
3
4

示例执行计划分析:

id select_type table type possible_keys key rows Extra
1 SIMPLE o range idx_date idx_date 1000 Using where
1 SIMPLE u eq_ref PRIMARY PRIMARY 1 NULL

分析要点:

  1. 连接查询中orders表使用范围扫描
  2. users表通过主键关联,使用eq_ref访问类型
  3. 可以考虑创建复合索引(order_date, status)来优化性能

通过对执行计划的深入理解和分析,我们可以更好地优化查询性能,提高数据库效率。

#执行计划#SQL优化
上次更新: 4/24/2025

← MySQL 快速分析binlog定位问题 DBA常用SQL和命令整理备查→

最近更新
01
tidb fast ddl
04-04
02
TiDB配置文件调优 原创
04-03
03
如何移除TiDB中的表分区 原创
04-03
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式