PmaControl logo PmaControl
  • 首页
  • PmaControl
    • AI智能代理 13个本地代理
    • 定价方案 Community、Cloud、On-Premise、Premium
    • 文档 指南、API、架构
    • 客户 28+企业
    • 常见问题 25个问题 / 7个类别
    数据库
    • MariaDB 30 篇文章
    • MySQL 10 篇文章
    • Galera Cluster 6 篇文章
    • MaxScale 3 篇文章
    • ProxySQL 2 篇文章
    • Amazon Aurora MySQL 0 篇文章
    • Azure Database 0 篇文章
    • ClickHouse 0 篇文章
    • GCP CloudSQL 0 篇文章
    • Percona Server 0 篇文章
    • SingleStore 0 篇文章
    • TiDB 0 篇文章
    • Vitess 0 篇文章
    解决方案
    • 全天候支持 MariaDB & MySQL紧急支持
    • Observabilité SQL 监控、告警、拓扑
    • Haute disponibilité 复制、故障转移、Galera
    • Disaster Recovery 备份、恢复、RPO/RTO
    • Sécurité & conformité 审计、GDPR、SOC2
    • Migration & upgrade 零停机、pt-osc、gh-ost
  • 定价方案
  • 资源
    • 文档 技术指南与API
    • 常见问题 25个常见问题
    • 客户评价 客户反馈与案例
    • 博客 文章与洞察
    • 路线图 即将推出的功能
    专业领域
    • Observabilité SQL 监控、告警、Dot3拓扑
    • Haute disponibilité 复制、故障转移、Galera
    • Sécurité & conformité 审计、GDPR、SOC2、ISO 27001
    • Disaster Recovery 备份、恢复、RPO/RTO
    • Performance & optimisation Digests、EXPLAIN、调优
    • Migration & upgrade 零停机、pt-osc
    快速链接
    • GitHub Wiki 26页 — 安装、引擎、插件
    • 源代码 GitHub官方仓库
    • 全天候支持 MariaDB & MySQL紧急支持
    • 预约演示 30分钟 — 真实架构
  • 全天候支持
  • 预约演示
预约演示
🇫🇷 FR Français 🇬🇧 EN English 🇵🇱 PL Polski 🇷🇺 RU Русский 🇨🇳 ZH 中文
← 返回博客

Performance Schema 与 PmaControl 仪表盘:追踪慢查询

发布于 2026年4月13日 作者 Aurélien LEQUOY
mariadb mysql performance-schema diagnostics pmacontrol
分享 X LinkedIn Facebook Email PDF
Performance Schema 与 PmaControl 仪表盘:追踪慢查询

Performance Schema:尚未开发的金矿

performance_schema 在 MariaDB / MySQL 中默认启用已有多年。然而,大多数 DBA 并不会日常使用它。原因很简单:原始数据难以阅读。数十张表、数百万行、累计计数器——没有聚合工具的话,这些只是噪音。

PmaControl 将噪音转化为信号。它通过 Aspirateur 收集 performance_schema 数据,通过 Listener(Digest::integrate)进行聚合,并以可操作的仪表盘呈现。本文将介绍从数据源到仪表盘的完整管道。

验证 performance_schema 是否已启用

MariaDB

SHOW GLOBAL VARIABLES LIKE 'performance_schema';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| performance_schema | ON    |
+--------------------+-------+

如果显示 OFF,请在配置文件中添加:

[mysqld]
performance_schema = ON

需要重启服务——此变量不支持动态修改。

MySQL

MySQL 上同样如此。该变量是只读的,需要重启:

[mysqld]
performance_schema = ON

性能影响

经典问题:"performance_schema 会拖慢我的服务器吗?"2026 年的答案是不会,影响无法察觉。在典型工作负载下,开销在 1-3% 范围内。可见性带来的收益远远超过这一成本。

唯一的例外:极高工作负载的服务器(每秒超过 100,000 次查询),每一个百分点都很重要。在这种情况下,应禁用不必要的探针,而不是完全关闭 performance_schema。

数据源:events_statements_summary_by_digest

PmaControl 利用的关键表是:

SELECT * FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10\G

该表包含按指纹(规范化签名)汇总的每个已执行查询的摘要。以下是最有用的列:

列 说明
DIGEST 指纹的唯一哈希
DIGEST_TEXT 规范化的查询文本(参数替换为 ?)
COUNT_STAR 总执行次数
SUM_TIMER_WAIT 总执行时间(以皮秒为单位)
AVG_TIMER_WAIT 每次执行的平均时间
SUM_ROWS_EXAMINED 检查的总行数
SUM_ROWS_SENT 返回的总行数
FIRST_SEEN 首次执行时间
LAST_SEEN 最后执行时间

指纹是核心:它将 SELECT * FROM users WHERE id = 42 和 SELECT * FROM users WHERE id = 1337 规范化为单一指纹 SELECT * FROM users WHERE id = ?。这样就可以不受参数值影响地聚合统计信息。

PmaControl 管道

第一步:Aspirateur 采集

Aspirateur 定期在每个受监控的服务器上执行以下查询:

SELECT
    DIGEST,
    DIGEST_TEXT,
    COUNT_STAR,
    SUM_TIMER_WAIT,
    AVG_TIMER_WAIT,
    SUM_ROWS_EXAMINED,
    SUM_ROWS_SENT,
    SUM_NO_INDEX_USED,
    SUM_NO_GOOD_INDEX_USED,
    FIRST_SEEN,
    LAST_SEEN
FROM performance_schema.events_statements_summary_by_digest
WHERE DIGEST IS NOT NULL
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 500;

LIMIT 500 是有意为之的:PmaControl 专注于按累计时间计算的前 500 个最耗时查询。快速且不频繁的查询对优化没有意义。

结果与时间戳一起存储在 ts_value_general_json 中。

第二步:Listener 处理

当 Listener 检测到新的摘要数据时,会触发 Digest::integrate()。该函数执行以下操作:

  1. 计算增量:由于 performance_schema 提供累计计数器(自上次 TRUNCATE 或重启以来),Digest::integrate 计算两次采集之间的差值以获取期间指标。

  2. 时间单位转换:将皮秒转换为毫秒以便显示。

  3. 计算百分位数:从分布中估算 P95(第 95 百分位)执行时间。

  4. 存储到 ts_mysql_digest_stat:专用的摘要统计表,按天分区并使用 RocksDB 引擎进行压缩。

Aspirateur
  -> SELECT FROM performance_schema(每分钟)
  -> INSERT INTO ts_value_general_json

Listener
  -> 检测新数据(ts_max_date 变化)
  -> Digest::integrate()
     -> 增量计算(当前 - 前一次)
     -> 转换为毫秒
     -> 估算 P95
     -> INSERT INTO ts_mysql_digest_stat

ts_mysql_digest_stat 表

这是摘要统计数据的长期存储:

CREATE TABLE ts_mysql_digest_stat (
    id BIGINT UNSIGNED AUTO_INCREMENT,
    server_id INT UNSIGNED,
    digest VARCHAR(64),
    digest_text TEXT,
    period_start DATETIME,
    period_end DATETIME,
    exec_count BIGINT UNSIGNED,
    total_time_ms DECIMAL(20,3),
    avg_time_ms DECIMAL(15,3),
    p95_time_ms DECIMAL(15,3),
    rows_examined BIGINT UNSIGNED,
    rows_sent BIGINT UNSIGNED,
    no_index_used BIGINT UNSIGNED,
    PRIMARY KEY (id),
    KEY idx_server_digest (server_id, digest, period_start)
) ENGINE=ROCKSDB
PARTITION BY RANGE (TO_DAYS(period_start)) (
    PARTITION p20260413 VALUES LESS THAN (TO_DAYS('2026-04-14')),
    PARTITION p20260414 VALUES LESS THAN (TO_DAYS('2026-04-15')),
    ...
);

按天分区实现了:

  • 快速清理:ALTER TABLE ts_mysql_digest_stat DROP PARTITION p20260401;
  • 快速的日期范围查询
  • 精细的数据保留控制

仪表盘

最耗时查询视图

主仪表盘显示按累计时间排序的最耗时查询:

排名  指纹                                      执行/小时   平均(ms)   P95(ms)  检查行数
----- ---------------------------------------- --------  --------  -------- ---------
  1   SELECT * FROM orders WHERE customer_id    12,430     45.2     234.5   1,245,000
      = ? AND status = ?
  2   UPDATE inventory SET stock = stock - ?     8,200     12.3      89.1     820,000
      WHERE product_id = ?
  3   SELECT o.*, c.name FROM orders o JOIN      3,150     78.9     445.2   3,150,000
      customers c ON o.customer_id = c.id
  4   INSERT INTO audit_log (...)                45,600      1.2       5.3          0
  5   SELECT COUNT(*) FROM sessions WHERE         980    234.5     890.1  98,000,000
      last_active < ?

每一行都可以点击以查看详细信息。

指纹详情视图

点击某个指纹后,PmaControl 会显示:

  • 完整文本:规范化查询的全文
  • 历史记录:过去 30 天平均执行时间和 P95 的变化趋势
  • 比率:rows_examined / rows_sent——高比率(>100:1)表示全表扫描或缺失索引
  • no_index_used 标志:多少次执行未使用索引

识别缺失的索引

rows_examined / rows_sent 比率是最强大的指标。来看一个例子:

指纹:SELECT * FROM orders WHERE customer_id = ?
检查行数:1,245,000(总计)
返回行数:12,430(总计)
比率:100:1

这个 100:1 的比率意味着 MariaDB / MySQL 检查了 100 行才返回 1 行。这是全表扫描或索引无效的典型迹象。

操作:检查 customer_id 上是否有索引:

SHOW INDEX FROM orders WHERE Column_name = 'customer_id';

如果索引不存在:

ALTER TABLE orders ADD INDEX idx_customer_id (customer_id);

SUM_NO_INDEX_USED 标志

PmaControl 会用红色标记 SUM_NO_INDEX_USED 值较高的查询。当 MariaDB / MySQL 执行全表扫描时会设置此标志——这通常是性能问题的头号原因。

从 PmaControl 执行 EXPLAIN

对于被识别为有问题的查询,PmaControl 可以直接执行 EXPLAIN:

EXPLAIN SELECT * FROM orders WHERE customer_id = 42 AND status = 'pending';

结果以颜色编码显示:

  • 绿色:type = ref 或 type = eq_ref——使用了索引,良好
  • 橙色:type = range——范围扫描,可接受
  • 红色:type = ALL——全表扫描,需要修复

与 Marina+ Agent 集成

Marina+ 是 PmaControl 的自动优化代理。它分析摘要数据并提出建议:

  1. 缺失索引:检测 rows_examined/rows_sent 比率高的查询,并建议创建索引
  2. 查询重写:识别低效模式(SELECT *、关联子查询、在非索引列上 ORDER BY)
  3. 配置调优:根据查询模式调整服务器参数(sort_buffer_size、join_buffer_size 等)

Marina+ 不会自动修改任何内容——它生成的建议需要 DBA 验证和应用。

与 PMM(Percona 监控管理)的比较

PMM 和 PmaControl 利用相同的数据源(performance_schema),但采用不同的方法:

方面 PmaControl PMM
数据源 performance_schema performance_schema + slowlog
代理 Aspirateur(SSH + MySQL) mysqld_exporter + QAN
存储 ts_mysql_digest_stat(RocksDB) ClickHouse(QAN)
指纹提取 服务器端(MariaDB / MySQL 原生) 客户端(Percona agent)
P95 从分布估算 从慢查询日志计算
历史记录 按天分区,可配置保留策略 ClickHouse,可配置保留策略
操作 集成 EXPLAIN,Marina+ 建议 Query Analytics + PMM UI

主要区别:PMM 结合了 performance_schema 和慢查询日志以获得更精确的百分位数。PmaControl 仅依赖 performance_schema,更轻量但粒度较粗。

PmaControl 的优势:与生态系统其他部分的集成(复制、拓扑、告警、操作)。PMM 在纯查询分析方面更出色,PmaControl 在全局基础设施视图方面更出色。

实战案例:发现并修复慢查询

场景:PmaControl 仪表盘显示某个查询消耗了服务器总时间的 40%。

第一步:识别

在最耗时查询仪表盘中:

#1  SELECT u.*, p.* FROM users u
    JOIN purchases p ON u.id = p.user_id
    WHERE p.created_at > ? AND u.country = ?

    执行/小时: 5,200   平均: 234ms   P95: 1,200ms   检查行数: 45M

第二步:分析

rows_examined / rows_sent 比率非常糟糕:每小时检查 4500 万行却仅返回约 5,200 个结果。

PmaControl 的 EXPLAIN 输出:

+----+------+----------+------+------+------+----------+
| id | type | table    | key  | rows | filt | Extra    |
+----+------+----------+------+------+------+----------+
|  1 | ALL  | users    | NULL | 1.2M | 10%  | where    |
|  1 | ref  | purchases| idx1 | 15   | 33%  | where    |
+----+------+----------+------+------+------+----------+

问题所在:users 表进行了全表扫描(type = ALL)。country 列上没有索引。

第三步:修复

ALTER TABLE users ADD INDEX idx_country (country);

第四步:验证

添加索引后,PmaControl 仪表盘在一小时内显示出改善:

#1  SELECT u.*, p.* FROM users u
    JOIN purchases p ON u.id = p.user_id
    WHERE p.created_at > ? AND u.country = ?

    执行/小时: 5,200   平均: 12ms   P95: 45ms   检查行数: 78K

平均时间从 234ms 降至 12ms(19 倍),检查行数从 4500 万降至 78K(577 倍)。

最佳实践

1. 不要手动 TRUNCATE performance_schema

PmaControl 计算两次采集之间的增量。如果您运行 TRUNCATE TABLE performance_schema.events_statements_summary_by_digest,计数器会从零重新开始,第一次增量计算将不正确。请让 PmaControl 来处理。

2. 必要时增加 performance_schema_digests_size

默认情况下,MariaDB / MySQL 存储前 N 个指纹。如果您的应用程序的不同查询数量超过限制,最不频繁的查询将被淘汰:

[mysqld]
performance_schema_digests_size = 10000  ; 默认约 5000

3. 与慢查询日志关联分析

PmaControl 通过 performance_schema 提供"什么"(哪些查询慢)。慢查询日志提供"何时"(在哪个确切时刻)。两者是互补的。

4. 关注 rows_examined / rows_sent 比率

这是最具可操作性的指标。比率 > 100:1 几乎总是意味着缺失索引。比率 > 1000:1 则是紧急问题。

5. 使用 P95,而非平均值

平均值会掩盖异常值。一个平均 10ms 但 P95 为 500ms 的查询存在间歇性问题(锁竞争、冷缓存、不稳定的执行计划)。P95 能揭示这些问题。

结论

Performance_schema 是 MariaDB / MySQL 查询优化的最佳数据源。PmaControl 通过 Aspirateur -> Digest::integrate -> ts_mysql_digest_stat -> 仪表盘的管道自动化了数据的收集、聚合和呈现。

结果:对最耗时的查询、缺失的索引和随时间变化的性能趋势拥有持续的可见性。结合 Marina+ 提供的自动化建议,这是一个完整的性能优化工作流——从发现到修复。

分享 X LinkedIn Facebook Email PDF
← 返回博客

评论 (0)

暂无评论。

发表评论

PmaControl
+33 6 63 28 27 47 contact@pmacontrol.com
法律声明 GitHub 联系我们
不要等到故障发生才了解您的架构。 © 2014-2026 PmaControl — 68Koncept