show profiles和show profile用于会话级实时性能分析:先set profiling=1启用,执行sql后用show profiles查query_id及总耗时,再用show profile for query n查看各阶段耗时;其数据内存存储、不存sql文本、重启即清空。
mysql 的 show profiles 和 show profile 怎么用
直接看执行耗时分布,不用翻慢日志或改配置。前提是服务端已开启 profiling(默认关闭)。
-
SET profiling = 1;启用当前会话的性能追踪 - 执行任意查询,比如
SELECT * FROM users WHERE id = 123; - 用
SHOW PROFILES;查所有已记录查询的 ID 和总耗时 - 再用
SHOW PROFILE FOR QUERY N;(N 是上一步看到的 Query_ID)看详细阶段耗时,比如Creating tmp table、Sorting result
注意:profiling 是会话级、内存中暂存的,重启连接或服务器就清空;不记录 SQL 文本本身,只记耗时分布 —— 想看原始 SQL,得配合其他方式。
如何拿到实际执行的完整 SQL(含参数展开)
MySQL 自身不提供“带值的原始语句”日志,general_log 能打出来,但代价高、不推荐线上开;更实用的是从客户端或代理层捕获。
- 如果用 Python +
mysql-connector-python,启用get_warnings=True并监听cursor._executed(非公开属性,慎用于生产) - 用
mysqldumpslow分析慢日志时,它默认会归一化 SQL(把数字/字符串替换成 ?),加-s t -t 10 -v可看带值的原始行(需确保慢日志已记录log_slow_verbosity=full) - Percona Server 或 MySQL 8.0+ 配合
performance_schema.events_statements_history_long表,查SQL_TEXT字段,但要注意:预编译语句显示的是带 ? 的模板,不是真实值
真正带值的原始 SQL,往往得靠应用层日志(如 ORM 的 echo=True 或 logging.DEBUG 级别输出)—— 数据库端天然不保存参数代入后的结果。
EXPLAIN FORMAT=TREE 和 FORMAT=JSON 谁更适合分析执行逻辑
FORMAT=TREE 更直观,适合快速判断是否走索引、有没有 Using filesort;FORMAT=JSON 包含更多底层决策信息,比如为什么没选某个索引、成本估算细节。
- 日常排查优先用
EXPLAIN FORMAT=TREE SELECT ...:嵌套缩进一眼看出驱动表、连接顺序、访问类型 - 需要确认优化器“怎么想的”,用
EXPLAIN FORMAT=JSON SELECT ...,重点看query_block下的cost_info和used_columns - 注意:JSON 输出里
table_name可能是<derived2></derived2>这类临时名,对应不上原 SQL 的表别名,得结合select_id对齐
两者都不显示真实执行时间,也不反映并发影响;它们只是预测,和 PROFILE 的实测数据互补,不能互相替代。
为什么 performance_schema 查不到刚跑完的查询
不是没记录,是默认配置太保守:历史事件表大小有限、采集开关没全开、或者语句太快被过滤了。
- 检查是否启用:确认
performance_schema开启(SELECT @@performance_schema;返回 1),且相关消费者已打开,比如UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_statements_history_long'; - 调大缓冲区:
performance_schema_events_statements_history_long_size默认才 1000 行,高并发下很快被覆盖 - 语句执行时间低于阈值(
performance_schema_max_sql_text_length或setup_instruments中的 timing 开关)也会被跳过
最常被忽略的一点:events_statements_history_long 只存“完成”的语句,如果查询卡在锁等待或网络发送阶段,它根本不会入库 —— 这时候得看 events_waits_current 或 innodb_trx。










