如何在MySQL中跟踪SQL执行过程中内部临时文件的生成大小

落明吖_2625

落明吖_2625

2026-10-24

850人浏览

原创

created_tmp_disk_tables与created_tmp_tables用于统计磁盘/内存临时表创建次数,比值超25%表明临时表下盘率过高;需结合flush status、explain及慢日志综合定位大临时文件成因。

如何在mysql中跟踪sql执行过程中内部临时文件的生成大小

查 Created_tmp_disk_tables 和 Created_tmp_tables 状态变量

MySQL 不直接暴露单条 SQL 生成的临时文件大小,但会统计会话或全局范围内内存/磁盘临时表的创建次数。这两个变量是第一道线索:Created_tmp_tables 表示所有临时表(含内存中)的创建次数,Created_tmp_disk_tables 表示其中落到磁盘的次数。只要后者 > 0,就说明有语句触发了磁盘临时表 —— 这通常意味着临时文件已生成,且大小可能远超 tmp_table_size 或 max_heap_table_size 的限制。

执行前先清空计数(仅限测试会话):

FLUSH STATUS;
再运行你的目标 SQL,然后查:
SHOW SESSION STATUS LIKE 'Created_tmp%';
注意对比两个值的差值,差得越多,越可能产生大临时文件。

用 EXPLAIN 预判是否走磁盘临时表

EXPLAIN 的 Extra 列里出现 Using temporary 是明确信号,但不区分内存还是磁盘。真正决定落盘的是查询涉及的数据量和当前会话的内存限制参数。关键看三个条件是否同时满足:

  • 查询包含 GROUP BY、DISTINCT、UNION 或某些 ORDER BY 场景
  • 结果集估算行数 × 平均行宽 > tmp_table_size(会话级)和 max_heap_table_size(取二者较小值)
  • 表结构含大字段(如 TEXT、BLOB、长 VARCHAR),哪怕只选一列,也会强制走磁盘临时表

所以不能只看 Using temporary,要结合 rows 和字段类型一起判断。比如 SELECT DISTINCT long_text_col FROM t WHERE ...,哪怕 rows 很小,也大概率落盘。

开启慢日志并配置 log_queries_not_using_indexes=ON 捕获隐式落盘行为

有些语句不会在 EXPLAIN 中显示 Using temporary,但实际执行时因排序缓冲区不足(sort_buffer_size 太小)而生成磁盘排序文件(/tmp/MLIxxxxx)。这类行为不会被 Created_tmp_* 统计,但会被慢日志记录 —— 只要你在启动时加了:

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
slow_query_log = ON<br>log_queries_not_using_indexes = ON<br>long_query_time = 0
然后执行语句,就能在慢日志里看到完整 SQL 和实际耗时,再配合 strace -p $(pgrep mysqld) -e trace=open,write(需 root)可观察是否真的打开了临时文件路径。

注意:线上慎开 long_query_time = 0,建议只在复现环境临时启用;log_queries_not_using_indexes 本身不记录临时文件大小,但它能帮你定位到那些“看起来不重、实际很重”的语句。

查 information_schema.PROCESSLIST 中的 Info 和 State 字段

当语句正在执行且卡在临时表阶段时,SHOW FULL PROCESSLIST 可能显示 State: Creating tmp table 或 State: Copying to tmp table on disk。此时如果 Info 字段还能看到原始 SQL(未被截断),就基本确认它正处于生成临时文件的过程中。但这个状态转瞬即逝,需要快速抓取,或者用轮询脚本持续监控:

while true; do mysql -Nse "SELECT ID,USER,HOST,DB,COMMAND,TIME,STATE,INFO FROM information_schema.PROCESSLIST WHERE STATE LIKE '%tmp%';" | grep -v '^$'; sleep 0.5; done

这招对偶发性大临时文件问题最有效,尤其是你怀疑某条定时任务 SQL 在凌晨触发了磁盘爆满时。

临时文件大小本身不会被 MySQL 主动记录,它取决于语句逻辑、数据分布、会话参数和引擎实现细节。真正要定位“谁写了多大临时文件”,得靠组合手段:先用状态变量圈范围,再用 EXPLAIN 排逻辑,辅以慢日志和进程状态抓现场。最容易被忽略的是 max_heap_table_size 这个会话级参数 —— 它默认和全局同值,但应用连接池常会覆盖,导致同一 SQL 在不同连接里行为不一致。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4463

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

931

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1169

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6421

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3203

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6380

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8721

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1190

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1032

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 189人学习