当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL 派生表物化后怎么判断临时表是否溢出磁盘

MySQL 派生表物化后怎么判断临时表是否溢出磁盘

来源:17golang原创 2026-09-08 21:43:11 0浏览 收藏

MySQL 派生表物化后是否“溢出磁盘”,不能只看一项计数。先用 EXPLAIN 确认目标子查询真的走了物化路径,再把 tmp_table_sizetemptable_max_ramCreated_tmp_disk_tables 和临时表空间放在同一条证据链里。尤其是 MySQL 8.x 的 TempTable 可能先使用内存映射文件,状态变量未必把这一步直接算进磁盘临时表。

要点速览
  • EXPLAIN 只能说明计划和物化关系,不能单独证明已经落盘。
  • Created_tmp_disk_tables 适合做趋势信号,但不能覆盖所有 TempTable 溢出场景。
  • 最终要结合 Performance Schema 的 physical_disk、InnoDB 临时表空间和磁盘剩余量判断风险。

先用 EXPLAIN 确认派生表确实进入物化路径

先不要急着调大内存参数。对包含 FROM 子查询的 SQL 执行 EXPLAIN FORMAT=TRADITIONAL 或 JSON 计划,确认计划中出现派生表相关节点。派生表可能被合并进外层查询,也可能被物化;如果根本没有物化,后面的临时表计数就不能简单归到它身上。

-- 只查看计划,不执行这条查询
EXPLAIN FORMAT=TRADITIONAL
SELECT d.customer_id, COUNT(*) AS item_count
FROM (
    -- 保留必要列,避免物化结果过宽
    SELECT customer_id, product_id
    FROM order_items
    WHERE created_at >= '2026-09-01'
) AS d
GROUP BY d.customer_id;

计划确认后,再记录派生表输出列数、过滤条件和聚合方式。一个包含宽字符串、重复行或大范围排序的派生结果,更容易触碰单个内存临时表的限制。

MySQL 派生表物化中 EXPLAIN、DERIVED、Materialize 与 TempTable 的静态关系图
图1:把 EXPLAIN 计划、派生表物化节点和 TempTable 资源边界对应起来,先确认要排查的对象。

对照内存临时表阈值解释为什么会转盘

MySQL 8.4 默认以内存 TempTable 处理内部临时表。tmp_table_size限制单个内部内存临时表;temptable_max_ram控制 TempTable 可占用的全局内存;temptable_max_mmaptemptable_use_mmap决定超过内存后是否经过内存映射文件。使用 MEMORY 引擎时,还要考虑 max_heap_table_sizetmp_table_size 中较小者。

-- 读取当前实例与会话的临时表相关边界
SHOW VARIABLES WHERE Variable_name IN (
    'internal_tmp_mem_storage_engine',
    'tmp_table_size',
    'max_heap_table_size',
    'temptable_max_ram',
    'temptable_max_mmap',
    'temptable_use_mmap',
    'tmpdir'
);

因此,“超过 tmp_table_size”和“已经占用可见磁盘文件”不是同一个判断。TempTable 的临时文件可能在创建后立即被打开并删除目录项,空间仍由操作系统占用;而 InnoDB on-disk internal temporary table 则会落到会话临时表空间。

用状态计数和 Performance Schema 做前后取样

最实用的排查方式是对同一连接做前后取样,不要拿服务器启动以来的累计值直接下结论。执行目标语句前后分别记录计数差值:

-- 先保存当前会话的累计值,避免把历史流量混进来
SHOW SESSION STATUS LIKE 'Created_tmp%';

-- 在两次采样之间执行目标查询

-- 再次采样,用前后差值判断本次查询的影响
SHOW SESSION STATUS LIKE 'Created_tmp%';

Created_tmp_tables增加,说明创建了内部临时表;Created_tmp_disk_tables增加,说明创建了内部磁盘临时表。但官方也说明,TempTable 使用内存映射文件时,这项磁盘计数存在覆盖不到的情况。可以再看 Performance Schema 的 TempTable 内存摘要:

-- 只读查看 TempTable 的内存与磁盘分配摘要
SELECT EVENT_NAME, CURRENT_NUMBER_OF_BYTES_USED
FROM performance_schema.memory_summary_global_by_event_name
WHERE EVENT_NAME IN (
    'memory/temptable/physical_ram',
    'memory/temptable/physical_disk'
);

如果 physical_disk出现非零值,说明 TempTable 曾经触及内存限制并使用了磁盘分配路径;如果两个状态变量都没有明显变化,则应回到执行计划检查目标派生表是否被合并,或确认查询是否被其他连接、其他语句干扰。

MySQL Created_tmp 状态变量、TempTable physical_disk 与 InnoDB 临时表空间的静态证据关系图
图2:将状态计数、TempTable 磁盘分配和 InnoDB 临时表空间放在同一张证据图中,避免只看一个指标。

检查 InnoDB 临时表空间并选择修复方向

当确认磁盘路径被使用后,继续检查 InnoDB 临时表空间和目录容量。下面的查询用于查看全局临时表空间元数据:

-- 查看 InnoDB 临时表空间文件的大小与上限
SELECT FILE_NAME, TABLESPACE_NAME, ENGINE,
       TOTAL_EXTENTS * EXTENT_SIZE AS total_size_bytes,
       DATA_FREE, MAXIMUM_SIZE
FROM INFORMATION_SCHEMA.FILES
WHERE TABLESPACE_NAME = 'innodb_temporary';

-- 查看全局临时表空间的自动扩展策略
SELECT @@innodb_temp_data_file_path;

修复顺序建议是:先缩小派生表输出列、提前过滤、补齐能减少排序或回表的索引;仍然需要大中间结果时,再根据并发量评估 tmp_table_sizetemptable_max_ram。最后给临时表空间设置可接受的上限并监控目录容量。直接把阈值调到很大,可能把单条查询的磁盘问题换成并发内存压力。

常见问题

Created_tmp_disk_tables 没增加,能断定没有落盘吗?

不能。TempTable 通过内存映射文件溢出时,官方文档明确指出该计数可能不覆盖它。应结合 memory/temptable/physical_disk 和临时表空间信息判断。

看到 DERIVED 就说明临时表已经写满磁盘了吗?

不是。DERIVED 说明计划里有派生表节点,是否物化、使用哪种存储路径和是否触碰阈值,要靠执行过程中的指标确认。

应该先调大 tmp_table_size 还是先改 SQL?

先改写和缩小中间结果通常更稳妥。只有在确认查询结构合理、并发内存预算充足时,才针对阈值做小范围调整。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go fuzzing 怎么把随机输入约束在合法字节范围Go fuzzing 怎么把随机输入约束在合法字节范围
上一篇
Go fuzzing 怎么把随机输入约束在合法字节范围
Go JSON Decoder.Decode 成功一次后如何发现尾部垃圾数据
下一篇
Go JSON Decoder.Decode 成功一次后如何发现尾部垃圾数据
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    30次使用
  • SuperCLUE中文大模型评测基准:功能、能力维度与应用指南
    SuperCLUE
    SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
    187次使用
  • C-Eval中文评测基准:大语言模型多学科能力评估指南
    C-Eval
    深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
    120次使用
  • AI Prompt Library:免费AI提示词库,助力ChatGPT高效创作与营销
    AI Prompt Library
    探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
    46次使用
  • Generrated:DALL·E 2/3 AI绘画提示词灵感库与图像对比平台
    Generrated
    Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
    28次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码