qps应基于queries差值除以uptime差值计算,因queries涵盖所有sql语句(含存储过程内执行),而com_select仅统计客户端select;tps必须用(com_commit + com_rollback)除以uptime差值,以完整反映事务完成压力。

不能靠 Com_select 算 QPS,也不能只用 Com_commit 算 TPS —— 这两个变量会漏掉关键操作,导致结果严重偏低。
为什么 Com_select 不等于 QPS 分子
QPS 是每秒执行的 SQL 语句总数,不是“只读查询数”。Com_select 只统计客户端发起的 SELECT 语句,完全不包含:
- 存储过程、函数、触发器内部执行的
SELECT -
SHOW、SET、DO、HELP等非 DQL 语句 - 由 MySQL 自身触发的元数据查询(如隐式打开表)
真正覆盖全部语句的是 Queries 状态变量 —— 它计入所有执行过的语句(除 COM_PING 和 COM_STATISTICS),且包含存储程序内执行的语句。官方文档明确将其定义为 “The number of statements executed by the server”。
Com_commit 单独使用会低估 TPS
TPS 应反映“事务完成压力”,而不仅仅是显式提交。只看 Com_commit 会漏掉:
- 自动提交模式下每条 DML(
INSERT/UPDATE/DELETE)触发的隐式提交 - DDL 操作(如
CREATE TABLE)引发的隐式提交 - 事务回滚产生的负载 ——
Com_rollback同样消耗引擎资源
因此生产环境通用公式是:TPS = (Com_commit + Com_rollback) / 时间差。这个和 InnoDB 实际事务生命周期(从开始到 COMMIT/ROLLBACK)对齐,DBA 关心的就是这个压力值。
采样时必须用两次 Uptime 差值,不能用脚本 sleep 时间
很多人写脚本先 sleep 1 再查一次状态,以为时间差就是 1 秒。但实际耗时包含网络往返、MySQL 响应、shell 调度等延迟,尤其在高负载时误差可达 10% 以上。
正确做法是同时采集 Queries 和 Uptime(或 Com_commit 和 Uptime):
- 第一次:获取
Queries和Uptime值(记为 Q1、U1) - 第二次:再获取
Queries和Uptime值(记为 Q2、U2) - QPS = (Q2 − Q1) / (U2 − U1)
Uptime 是 MySQL 自身记录的运行秒数,精度毫秒级,且不受客户端延迟影响 —— 这才是真实的时间跨度。
快速验证命令别依赖 mysqladmin status 第6列
mysqladmin -uroot -p status 输出的第6列确实是 Queries 值,但它只给当前快照,无法自动做差。想盯屏看实时波动,要用:
mysqladmin -uroot -p -i1 extended-status -r | awk '/^(Queries|Com_commit|Com_rollback)$/ {print $1, $2}'
其中 -r 参数启用自动差值模式,-i1 表示每秒刷新 —— 这样输出的就是每秒增量,无需手动计算。注意字段名大小写敏感,Com_commit 必须全小写匹配。
真正容易被忽略的是:Com_commit 和 Com_rollback 在 MySQL 重启后归零,但 Queries 不会重置;如果监控系统未处理指标重置(counter reset),长期运行后可能误判突增。这点在 Prometheus 场景下由 rate() 函数自动处理,但 shell 脚本需自行判断负值并修正。











