需先确认performance_schema是否启用,若未启用则无法查看语句执行记录;启用后可通过events_statements_summary_by_user_by_event_name快速定位高频用户及语句类型,但需结合users表和table_io_waits_summary_by_table评估真实影响,并谨慎使用events_statements_history_long。
查用户操作频次,先确认 performance_schema 是否启用
mysql 默认可能没开 performance_schema,不启用就根本看不到任何语句执行记录。别急着写 sql,先看配置:
- 运行
SHOW VARIABLES LIKE 'performance_schema';,返回ON才算生效 - 如果返回
OFF,需在my.cnf中加performance_schema=ON并重启 mysqld - 即使开启,
events_statements_summary_by_user_by_event_name这类汇总表默认只统计 top 100 用户,小号用户可能被截断 —— 要调大performance_schema_max_user_classes
用 events_statements_summary_by_user_by_event_name 快速筛高频用户
这张表按用户 + SQL 类型聚合,适合快速定位“谁在频繁执行什么”。但它不存原始时间戳或具体 SQL 文本,只记次数、延迟、锁等待等统计值。
- 查某用户(比如
'app_user'@'%')的总执行次数:SELECT SUM(COUNT_STAR) FROM performance_schema.events_statements_summary_by_user_by_event_name WHERE USER = 'app_user';
- 想看该用户最常执行的 3 种语句类型:
SELECT EVENT_NAME, COUNT_STAR FROM performance_schema.events_statements_summary_by_user_by_event_name WHERE USER = 'app_user' ORDER BY COUNT_STAR DESC LIMIT 3;
- 注意:这里的
EVENT_NAME是statement/sql/select这类分类名,不是原始 SQL;要查具体语句得切到events_statements_history_long表,但那张表默认关闭且消耗大
关联 users 表和 table_io_waits_summary_by_table 看真实影响面
单看语句频次容易误判——比如一个用户每秒跑 100 条 SELECT 1,其实无害;但另一用户每分钟跑 5 次 UPDATE orders SET status=... WHERE user_id=? 却可能锁表。得结合资源消耗看。
- 先确认该用户是否真实存在且活跃:
SELECT * FROM performance_schema.users WHERE USER = 'app_user';(看CURRENT_CONNECTIONS和TOTAL_CONNECTIONS) - 再查它操作最多的表:
SELECT OBJECT_SCHEMA, OBJECT_NAME, COUNT_READ, COUNT_WRITE FROM performance_schema.table_io_waits_summary_by_table WHERE OBJECT_SCHEMA NOT IN ('mysql', 'performance_schema', 'information_schema') ORDER BY COUNT_READ + COUNT_WRITE DESC LIMIT 5; - 如果发现
orders表的COUNT_WRITE高,且对应用户也在高频列表里,才值得进一步抓取其慢日志或events_statements_history_long
避免掉进 events_statements_history_long 的坑
这张表能查到带 SQL 文本的原始记录,但代价高:默认关闭、内存占用大、滚动覆盖快,且需要额外权限。
- 启用前必须确认:
SET GLOBAL performance_schema_events_statements_history_long_size = 10000;(默认是 0) - 查的时候别用
WHERE USER = 'xxx'直接过滤 —— 这张表没有索引,全表扫描极慢;先用LIMIT取最近一批,再用应用层筛选 - 更稳妥的做法:配合慢查询日志(
slow_query_log)+log_queries_not_using_indexes,对高频用户单独开启long_query_time = 0临时捕获 - 注意权限:
SELECT权限不够,得有SELECTonperformance_schema.*,且用户不能是root@localhost(某些版本限制)
真正难的不是查出数字,而是判断哪个“高频”背后是业务逻辑缺陷、哪个是监控误报、哪个是攻击试探。表里看到的 COUNT_STAR 再大,也得回到业务上下文里验——比如定时任务重试、前端重复提交、还是 SDK 自动心跳。数据只是线索,不是结论。










