【MySQL 进阶之路】SQL 性能分析

4.SQL 性能分析笔记

在 MySQL 中进行性能分析是数据库优化的重要一环。通过识别性能瓶颈,优化 SQL 查询和数据库配置,可以显著提高应用的响应速度和吞吐量。以下是 MySQL 性能分析的进阶笔记,涵盖了常见的性能分析方法和工具。

1. 查询缓存(Query Cache)

MySQL 提供了查询缓存(query_cache),缓存已经执行过的查询结果,以提高后续相同查询的执行速度。但它的使用效果在高并发的情况下可能会降低性能,从 MySQL 5.7.20 开始, 查询缓存已经被废弃。

启用查询缓存:
sql 复制代码
SET GLOBAL query_cache_type = 1;
SET GLOBAL query_cache_size = 1048576;  -- 1MB 缓存
注意事项:
  • 查询缓存对于 INSERTUPDATEDELETE 等修改数据的操作没有太大作用,反而可能增加性能开销。
  • 查询缓存适合读取频繁但变化较少的场景。

2. EXPLAIN 分析查询执行计划

EXPLAIN 是分析 SQL 查询执行计划的一个常用工具,它帮助我们了解 MySQL 如何执行查询,包括使用哪些索引、如何扫描数据等。其基本用法如下:

sql 复制代码
EXPLAIN SELECT * FROM users WHERE age > 25;

EXPLAIN 输出解释:

字段 含义
id 查询的标识符,标识不同的查询步骤
select_type 查询类型,例如:SIMPLE(简单查询)、PRIMARY(最外层查询)、SUBQUERY(子查询)等
table 表名,表示该步骤操作的表
type 连接类型,表示 MySQL 如何查找数据,性能由 type 的值决定,常见的有:ALL(全表扫描)、index(索引扫描)、range(范围扫描)、ref(使用索引进行查找)、const(常数查询)等
possible_keys 可能使用的索引
key 实际使用的索引
key_len 使用的索引长度
ref 表示索引是如何与其他表的字段进行连接的
rows 扫描的行数估计值
Extra 额外信息,表示查询执行的附加信息,如 Using whereUsing index

优化建议:

  • 如果 typeALL,意味着查询使用了全表扫描,可以考虑添加合适的索引来优化。
  • 如果 rows 数量很大,可能需要进一步检查查询条件和表结构。
  • 关注 Extra 字段,查看是否存在全表扫描、临时表等性能瓶颈。

3. 慢查询日志

MySQL 提供了慢查询日志(slow_query_log),记录所有执行时间超过指定阈值的查询。启用慢查询日志后,可以分析慢查询并优化。

启用慢查询日志:
sql 复制代码
SET GLOBAL slow_query_log = 1;
SET GLOBAL slow_query_log_file = '/path/to/slow-query.log';
SET GLOBAL long_query_time = 2;  -- 查询时间大于1秒的都会被记录
分析慢查询日志:

通过 mysqldumpslowpt-query-digest 等工具分析慢查询日志,找出哪些查询执行时间过长、哪些查询需要优化。

3. 查看 SQL 执行频次

通过执行 SHOW GLOBAL STATUS LIKE 'Com%' 命令,可以查看 MySQL 系统中所有执行过的 SQL 命令的频次统计。这些统计数据可以帮助我们了解哪些 SQL 操作在系统中最为频繁,并根据执行频次来判断是否需要优化某些查询或操作。

常见的 Com% 状态变量:
  • Com_select :执行 SELECT 查询的次数
  • Com_insert :执行 INSERT 查询的次数
  • Com_update :执行 UPDATE 查询的次数
  • Com_delete :执行 DELETE 查询的次数
  • Com_create_table:创建表的次数
  • Com_drop_table:删除表的次数
  • Com_commit:事务提交的次数
  • Com_rollback:事务回滚的次数

通过查看这些统计信息,您可以识别出哪些操作是系统中频繁执行的。例如,如果 Com_select 的值异常高,而其他如 Com_insertCom_update 的值较低,这可能意味着查询操作频繁,而数据修改较少,您可以从查询优化方面入手。

示例:
sql 复制代码
SHOW GLOBAL STATUS LIKE 'Com%';

输出示例:

sql 复制代码
+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| Com_select             | 150000  |
| Com_insert             | 50000   |
| Com_update             | 20000   |
| Com_delete             | 10000   |
| Com_create_table       | 5       |
| Com_drop_table         | 3       |
+------------------------+---------+

通过分析这些数据,您可以看到最频繁的操作类型,从而做针对性的优化。


4. 查询性能分析

SHOW PROFILES 命令用于查看 SQL 查询的执行性能,可以帮助开发人员查看查询执行的各个阶段耗时,进一步发现查询性能瓶颈。SHOW PROFILES 返回的是在当前会话中执行过的所有 SQL 查询的时间统计信息,包括每个查询的总执行时间、各个阶段的时间消耗等。

启用 profiling 功能:

在 MySQL 5.0 及以上版本中,profiling 默认是禁用的。如果需要使用该功能,您需要先通过以下命令启用它:

sql 复制代码
SET profiling = 1;
使用 SHOW PROFILES 查询执行时间:

执行完查询后,可以使用 SHOW PROFILES 来查看执行过的 SQL 语句以及各个阶段的执行时间。

sql 复制代码
SHOW PROFILES;

输出示例:

sql 复制代码
+------+------------------------------------------+-----------+
| Query_ID | Query                                  | Duration  |
+---------+----------------------------------------+-----------+
| 1       | SELECT * FROM users WHERE age > 25     | 0.002300  |
| 2       | SELECT * FROM orders WHERE order_id=123| 0.001500  |
+---------+----------------------------------------+-----------+
  • Query_ID: 查询的唯一标识符
  • Query: 执行的 SQL 查询
  • Duration: 执行时间(秒)
查看查询执行的详细阶段:

通过 SHOW PROFILE FOR QUERY <query_id> 可以查看指定查询的详细执行阶段信息,如解析、优化、执行等各个阶段的耗时。

sql 复制代码
SHOW PROFILE FOR QUERY 1;

输出示例:

sql 复制代码
+--------------------------+----------+
| Status                   | Duration |
+--------------------------+----------+
| starting                 | 0.000030 |
| reading from net         | 0.000340 |
| preparing                | 0.000020 |
| executing                | 0.000250 |
| sending data             | 0.000180 |
| end                      | 0.000010 |
| query end                | 0.000080 |
| closing tables           | 0.000060 |
| freeing items            | 0.000020 |
| cleaning up              | 0.000010 |
+--------------------------+----------+

字段解释

  • Status : 查询的执行状态(例如 startingexecutingsending data 等)
  • Duration: 每个阶段的执行时间,单位是秒

通过分析这些阶段的耗时,您可以找出查询中最耗时的部分,并做针对性的优化。例如,如果 reading from net 阶段耗时较长,可能是因为网络延迟或查询结果集过大;如果 sending data 阶段耗时较长,可能是因为 MySQL 在处理大量数据。


总结

MySQL 性能优化是一个不断调优的过程,从硬件配置到查询结构优化再到索引设计,都需要全面考虑。利用 EXPLAIN 分析执行计划、慢查询日志、索引优化、内存调优等手段,可以有效提升数据库的性能。在高并发、大数据量的场景下,分库分表、查询缓存、连接优化等技术也是不可或缺的工具。

相关推荐
DKPT1 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
tan180°3 小时前
MySQL表的操作(3)
linux·数据库·c++·vscode·后端·mysql
满昕欢喜3 小时前
SQL Server从入门到项目实践(超值版)读书笔记 20
数据库·sql·sqlserver
巴伦是只猫3 小时前
【机器学习笔记Ⅰ】13 正则化代价函数
人工智能·笔记·机器学习
DuelCode4 小时前
Windows VMWare Centos Docker部署Springboot 应用实现文件上传返回文件http链接
java·spring boot·mysql·nginx·docker·centos·mybatis
幽络源小助理4 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
爬山算法5 小时前
MySQL(116)如何监控负载均衡状态?
数据库·mysql·负载均衡
JAVA学习通6 小时前
Mybatis--动态SQL
sql·tomcat·mybatis
X_StarX9 小时前
【Unity笔记02】订阅事件-自动开门
笔记·学习·unity·游戏引擎·游戏开发·大学生
MingYue_SSS9 小时前
开关电源抄板学习
经验分享·笔记·嵌入式硬件·学习