好嘞,各位观众老爷,今天咱们来聊聊 MySQL Performance Schema 里的一个宝贝疙瘩:events_statements_summary_by_digest
。这玩意儿啊,就好比你的数据库的 "黑匣子",能帮你揪出藏在代码深处的慢查询 “元凶”。准备好了吗?咱们这就开始一场"性能侦探"之旅!🕵️♂️
开场白:慢查询,数据库的“慢性病”
想象一下,你的网站响应速度慢如蜗牛🐌,用户体验直线下降📉。 这时候,十有八九是数据库出了问题,而慢查询就是那个潜伏的“慢性病”,一点点蚕食你的系统性能。
慢查询就像躲在暗处的刺客,表面风平浪静,实际背后捅刀子🔪。 你必须找到他们,绳之以法,才能让你的数据库重新焕发活力。
Performance Schema:你的“性能透视镜”
MySQL Performance Schema,顾名思义,就是用来监控 MySQL 性能的。它就像一个“性能透视镜”,能让你深入了解数据库内部的各种活动,包括查询执行、锁竞争、IO 操作等等。
但 Performance Schema 默认是关闭的,就像一个蒙着灰尘的宝藏,需要你亲自去发掘。
启用 Performance Schema:开启“性能侦探”模式
要启用 Performance Schema,需要在 MySQL 的配置文件(通常是 my.cnf
或 my.ini
)中进行配置:
[mysqld]
performance_schema=ON
修改配置后,重启 MySQL 服务。重启就像给你的数据库做了一次 “全身检查”,让它准备好迎接性能监控的挑战。
events_statements_summary_by_digest
:慢查询的“指纹库”
现在,重头戏来了!events_statements_summary_by_digest
表,就是我们今天要重点关注的“指纹库”。 它的作用是:
-
归纳总结: 它会将相似的 SQL 语句归纳成一个 "摘要" (digest),忽略掉具体的参数值,只关注 SQL 语句的结构。 比如,
SELECT * FROM users WHERE id = 1
和SELECT * FROM users WHERE id = 2
会被归纳成同一个摘要。 -
统计分析: 它会统计每个摘要的执行次数、总耗时、平均耗时、最大耗时、锁定时间、扫描行数等等关键指标。
简单来说,它就是把你的数据库中执行过的所有 SQL 语句都记录下来,并按照相似度进行分组,然后统计每个组的性能数据。这就像警察局的指纹库,可以帮助你快速找到那些“惯犯”。
events_statements_summary_by_digest
的结构:解读“指纹”
让我们来看看 events_statements_summary_by_digest
表里都有哪些字段:
字段名 | 数据类型 | 描述 |
---|---|---|
SCHEMA_NAME |
VARCHAR(64) | 数据库名。 |
DIGEST |
VARCHAR(32) | SQL 语句的摘要(MD5 哈希值)。 这就是 SQL 语句的“指纹”。 |
DIGEST_TEXT |
VARCHAR(1024) | SQL 语句的示例。 Performance Schema 会选择一个具有代表性的 SQL 语句作为示例,方便你理解这个摘要对应的 SQL 语句是什么。 |
COUNT_STAR |
BIGINT | SQL 语句的执行次数。 |
SUM_TIMER_WAIT |
BIGINT | SQL 语句的总执行时间(皮秒)。 皮秒是很小的时间单位,需要进行转换才能方便阅读。 |
MIN_TIMER_WAIT |
BIGINT | SQL 语句的最小执行时间(皮秒)。 |
AVG_TIMER_WAIT |
BIGINT | SQL 语句的平均执行时间(皮秒)。 |
MAX_TIMER_WAIT |
BIGINT | SQL 语句的最大执行时间(皮秒)。 |
SUM_LOCK_TIME |
BIGINT | SQL 语句的总锁定时间(皮秒)。 锁定时间是指 SQL 语句在等待锁资源时所花费的时间。 如果锁定时间过长,说明存在锁竞争问题。 |
SUM_ROWS_AFFECTED |
BIGINT | SQL 语句影响的总行数。 对于 SELECT 语句,这个值通常为 0。 对于 INSERT 、UPDATE 、DELETE 语句,这个值表示受影响的行数。 |
SUM_ROWS_SENT |
BIGINT | SQL 语句返回的总行数。 这个值只对 SELECT 语句有效。 |
SUM_ROWS_EXAMINED |
BIGINT | SQL 语句扫描的总行数。 扫描行数是指 MySQL 在执行 SQL 语句时需要检查的行数。 如果扫描行数过多,说明 SQL 语句没有使用到索引,或者索引效率不高。 |
SUM_CREATED_TMP_DISK_TABLES |
BIGINT | SQL 语句创建的磁盘临时表的数量。 如果 SQL 语句需要创建大量的磁盘临时表,说明查询复杂度很高,需要优化。 |
SUM_CREATED_TMP_TABLES |
BIGINT | SQL 语句创建的内存临时表的数量。 |
SUM_SELECT_FULL_JOIN |
BIGINT | SQL 语句执行全连接的次数。 全连接是一种效率很低的连接方式,应该尽量避免。 |
SUM_SELECT_FULL_RANGE_JOIN |
BIGINT | SQL 语句执行范围连接的次数。 |
SUM_SELECT_RANGE |
BIGINT | SQL 语句执行范围查询的次数。 |
SUM_SELECT_RANGE_CHECK |
BIGINT | SQL 语句执行范围检查的次数。 |
SUM_SELECT_SCAN |
BIGINT | SQL 语句执行全表扫描的次数。 全表扫描是一种效率很低的查询方式,应该尽量避免。 |
SUM_SORT_MERGE_PASSES |
BIGINT | SQL 语句执行排序合并的次数。 |
SUM_SORT_RANGE |
BIGINT | SQL 语句执行范围排序的次数。 |
SUM_SORT_ROWS |
BIGINT | SQL 语句排序的总行数。 |
SUM_SORT_SCAN |
BIGINT | SQL 语句执行全表排序的次数。 |
FIRST_SEEN |
TIMESTAMP | SQL 语句第一次被执行的时间。 |
LAST_SEEN |
TIMESTAMP | SQL 语句最后一次被执行的时间。 |
SUM_ERRORS |
BIGINT | SQL 语句执行错误的次数. |
SUM_WARNINGS |
BIGINT | SQL 语句执行产生警告的次数. |
这些字段就像一张张“性能标签”,详细记录了每条 SQL 语句的“健康状况”。
实战演练:揪出慢查询“元凶”
有了“指纹库”,接下来就是实战演练了。 我们可以通过 SQL 查询来分析 events_statements_summary_by_digest
表,找到那些性能瓶颈。
案例 1:找出执行时间最长的 SQL 语句
SELECT
DIGEST_TEXT,
COUNT_STAR,
SUM_TIMER_WAIT / 1000000000000 AS total_latency, -- 转换为秒
AVG_TIMER_WAIT / 1000000000000 AS avg_latency, -- 转换为秒
MAX_TIMER_WAIT / 1000000000000 AS max_latency, -- 转换为秒
SCHEMA_NAME
FROM
performance_schema.events_statements_summary_by_digest
ORDER BY
SUM_TIMER_WAIT DESC
LIMIT 10;
这条 SQL 语句会列出执行时间最长的 10 条 SQL 语句,包括 SQL 语句的示例、执行次数、总耗时、平均耗时、最大耗时以及数据库名。
通过分析这些 SQL 语句,我们可以找到那些耗时大户,然后重点优化。
案例 2:找出扫描行数最多的 SQL 语句
SELECT
DIGEST_TEXT,
COUNT_STAR,
SUM_ROWS_EXAMINED,
SCHEMA_NAME
FROM
performance_schema.events_statements_summary_by_digest
ORDER BY
SUM_ROWS_EXAMINED DESC
LIMIT 10;
这条 SQL 语句会列出扫描行数最多的 10 条 SQL 语句。 扫描行数越多,说明 SQL 语句可能没有使用到索引,或者索引效率不高。
案例 3:找出锁定时间最长的 SQL 语句
SELECT
DIGEST_TEXT,
COUNT_STAR,
SUM_LOCK_TIME / 1000000000000 AS total_lock_time, -- 转换为秒
SCHEMA_NAME
FROM
performance_schema.events_statements_summary_by_digest
ORDER BY
SUM_LOCK_TIME DESC
LIMIT 10;
这条 SQL 语句会列出锁定时间最长的 10 条 SQL 语句。 如果锁定时间过长,说明存在锁竞争问题,需要优化 SQL 语句或者调整数据库的并发参数。
案例 4:找出错误次数最多的 SQL 语句
SELECT
DIGEST_TEXT,
COUNT_STAR,
SUM_ERRORS,
SCHEMA_NAME
FROM
performance_schema.events_statements_summary_by_digest
ORDER BY
SUM_ERRORS DESC
LIMIT 10;
这条 SQL 语句会列出错误次数最多的 10 条 SQL 语句。 找出这些 SQL 语句,可以帮助你发现代码中的 bug 或者数据库配置问题。
优化建议:对症下药,药到病除
找到了慢查询“元凶”,接下来就是优化了。 优化方法有很多,比如:
-
添加索引: 这是最常见的优化手段。 通过添加索引,可以大大减少 SQL 语句的扫描行数,提高查询效率。
-
优化 SQL 语句: 避免使用
SELECT *
,尽量只查询需要的字段。 避免在WHERE
子句中使用函数或者表达式,尽量使用索引。 -
重写 SQL 语句: 有时候,简单的修改 SQL 语句的写法,就可以大大提高查询效率。
-
调整数据库配置: 调整数据库的内存大小、缓冲区大小、并发参数等等,可以提高数据库的整体性能。
-
升级硬件: 如果以上方法都无效,那就只能升级硬件了。 增加 CPU 核心数、内存大小、磁盘 IO 速度等等,可以提高数据库的处理能力。
注意事项:细节决定成败
在使用 events_statements_summary_by_digest
表时,需要注意以下几点:
-
Performance Schema 的开销: 启用 Performance Schema 会带来一定的性能开销。 如果你的数据库压力很大,建议只启用必要的监控项。
-
数据清理:
events_statements_summary_by_digest
表的数据会不断增长,需要定期清理。 可以使用TRUNCATE TABLE
命令来清空表数据。 -
数据采样: Performance Schema 默认会采样一部分 SQL 语句。 如果需要监控所有的 SQL 语句,需要调整采样参数。
-
权限问题: 只有具有
PROCESS
权限的用户才能访问events_statements_summary_by_digest
表。
总结:让数据库飞起来🚀
events_statements_summary_by_digest
表是 MySQL Performance Schema 中一个非常强大的工具,可以帮助你快速找到数据库的性能瓶颈,并进行优化。
掌握了 events_statements_summary_by_digest
,你就拥有了一双“火眼金睛”,能够洞察数据库的运行状况,让你的数据库飞起来!
结尾:性能优化,永无止境
性能优化是一个永无止境的过程。 随着业务的发展,数据库的压力会越来越大,需要不断地进行优化。 希望今天的分享能够帮助你在性能优化的道路上更进一步。
各位观众老爷,咱们下期再见!👋