【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 分析执行计划、慢查询日志、索引优化、内存调优等手段,可以有效提升数据库的性能。在高并发、大数据量的场景下,分库分表、查询缓存、连接优化等技术也是不可或缺的工具。

相关推荐
豆沙沙包?1 小时前
8.学习笔记-Maven进阶(P82-P89)
笔记·学习·maven
小黑屋的黑小子2 小时前
【MySQL】MySQL索引与事务
数据库·mysql·oracle
艺杯羹5 小时前
JDBC之ORM思想及SQL注入
数据库·sql·jdbc·orm·sql注入
blackA_5 小时前
数据库MySQL学习——day4(更多查询操作与更新数据)
数据库·学习·mysql
qq_441996057 小时前
为何 RAG 向量存储应优先考虑 PostgreSQL + pgvector 而非 MySQL?
数据库·mysql·postgresql
weixin_307779137 小时前
Azure Data Factory ETL设计与调度最佳实践
数据仓库·性能优化·云计算·azure·etl
刘婉晴8 小时前
【信息安全工程师备考笔记】第三章 密码学基本理论
笔记·安全·密码学
AI军哥8 小时前
MySQL8的安装方法
人工智能·mysql·yolo·机器学习·deepseek
程序员不想YY啊8 小时前
MySQL元数据库完全指南:探秘数据背后的数据
数据库·mysql·oracle
晓数10 小时前
【硬核干货】JetBrains AI Assistant 干货笔记
人工智能·笔记·jetbrains·ai assistant