MySQL 能不能直接查近3个月SQL访问量?结论先给你
一、对应达梦 V$SQL_HISTORY 的 MySQL 内存表:完全不能查3个月
MySQL 里 performance_schema.events_statements_history / events_statements_history_long 等同于达梦 V$SQL_HISTORY,硬性限制:
- 纯内存存储,重启全部清空;
- 默认
history_long仅存 10000条 全局SQL,新数据进来旧记录直接覆盖; - 高并发库可能几十分钟就把历史冲干净,最多只能看最近几十分钟/1~2小时;
- 无法持久化,不可能查到3个月前数据。
示例(只能查近期,3个月区间返回0)
SELECTCOUNT(*) total_sql,SUM(CASE WHEN SQL_TEXT LIKE 'SELECT%' THEN 1 ELSE 0 END) select_cnt,SUM(CASE WHEN SQL_TEXT REGEXP '^(INSERT|UPDATE|DELETE)' THEN 1 ELSE 0 END) dml_cntFROM performance_schema.events_statements_history_longWHERE EVENT_TIME >= NOW() - INTERVAL 3 MONTH; -- 近3个月,几乎无数据
二、MySQL 四种可行方案(按长期统计需求排序)
方案1:定时快照入库(轻量、推荐做月度报表,不开全量日志)
原理:SHOW GLOBAL STATUS LIKE 'Com_%' 是数据库启动后累计计数器,无时间戳,不能直接查历史;
show global status like 'Com_%';
写定时脚本(crontab 每小时/每半小时)采集 Com_select/Com_insert/Com_update/Com_delete/Questions,存入自建统计表,带采集时间。
后续直接查统计表,用期末值 - 期初值得到任意月份/3个月总SQL访问量。
- 自建统计表
CREATE TABLE mysql_sql_stat (id BIGINT AUTO_INCREMENT PRIMARY KEY,stat_time DATETIME,com_select BIGINT,com_insert BIGINT,com_update BIGINT,com_delete BIGINT,total_qps BIGINT);
- 统计近3个月总访问量
优点:性能损耗极小,适合长期统计日报、季报; 缺点:没有单条SQL明细,只有汇总总量。-- 取3个月前最早一条快照、当前最新快照,差值就是总量SELECT(curr.com_select - old.com_select) AS total_select,(curr.com_insert - old.com_insert) AS total_insert,(curr.com_update - old.com_update) AS total_update,(curr.com_delete - old.com_delete) AS total_deleteFROM mysql_sql_stat curr, mysql_sql_stat oldWHERE curr.stat_time = (SELECT MAX(stat_time) FROM mysql_sql_stat)AND old.stat_time <= NOW() - INTERVAL 3 MONTHORDER BY old.stat_time DESC LIMIT 1;
方案2:开启全量通用日志 general_log(可查任意3个月明细,线上不推荐长期开)
- 开启后每条SQL落地磁盘日志,带精确时间戳,日志切割归档保存3个月以上;
- 可用
grep、pt-query-digest筛选时间段统计SQL条数; 致命缺点:全量写入磁盘,高QPS库IO压力暴增,仅临时排查使用,不适合长期打开做常规统计。
方案3:审计日志(MySQL Enterprise Audit,企业版付费)
官方审计插件,持久化存储每条执行SQL+操作时间,支持直接SQL按时间区间COUNT统计,完美支持近3个月;社区版无此功能。
方案4:Binlog 间接统计(仅DML,不含SELECT)
binlog 只记录增删改,查不到SELECT查询量,只能统计写入操作,无法完整统计数据库总访问量。
三、对比达梦 & MySQL 能否查3个月
| 方式 | 达梦 | MySQL | 能否查近3个月 |
|---|---|---|---|
| 内存SQL历史视图(V$SQL_HISTORY / events_statements_history_long) | 内存循环覆盖 | 内存循环覆盖 | ❌ 不能 |
| 定时快照自建汇总表 | V$SYSSTAT差值 | Com_xxx差值 | ✅ 能(只有汇总) |
| 全量SQL日志/SVR_LOG | SVR_LOG持久化 | general_log文件 | ✅ 能(明细,耗IO) |
| 审计持久化表 | V$AUDITRECORDS | 企业版Audit插件 | ✅ 能(明细,付费) |
四、如果你要做「近3个月数据库访问量报表」最优方案
- 生产环境首选:定时脚本采集Com_xxx入库,无性能损耗,按月汇总总量;
- 需要明细SQL、区分每条SQL执行次数:归档 general_log 日志,定时解析入库;
- 社区版MySQL没有原生持久化SQL历史表,不像达梦审计开箱即用,必须靠日志/自建快照实现长期区间统计。
补充:数据库访问流量(应用与MySQL传输流量)
MySQL 默认无内置时段流量统计,两种方式:
- 服务器层
tcpdump抓3306端口流量,归档统计; - 中间件(MyCat、Sharding-JDBC)采集交互字节存入监控库。
