mysql版本:8.0.30
普通临时表
用户创建临时表(只有创建临时表的会话才能查看其创建的临时表的内容)
CREATE TEMPORARY TABLE t1 (c1 INT PRIMARY KEY) ENGINE=INNODB; --- 可以创建和普通表同名临时表,其他会话可以看到普通表(因为看不到其他会话创建的临时表); CREATE TABLE t1 (c1 INT PRIMARY KEY) ENGINE=INNODB; --- 当存在同名的临时表时,会话都是优先处理临时表(而不是普通表), --- 包括:select、update、delete、drop、alter 等操作
回收时机
-
会话断开,自动回收用户创建的临时表;
-
可以通过 drop table 删除用户创建的临时表,例如:drop table t1;
内部临时表
产生场景(更多可参考官方文档)
-
SQL 包含 union | union distinct 关键字
-
SQL 中存在派生表
-
SQL 中包含 with 关键字
-
SQL 中的order by 和 group by 的字段不同
-
SQL 为多表 update
-
SQL 中包含 distinct 和 order by 两个关键字
简单判断方式
-
执行计划中Extra包含了Using temporary ,或者包含 Using filesort (使用文件排序,临时文件)
-
查询information_schema.innodb_session_temp_tablespaces,若表的 ID 列变为了show processlist 中的 id 列的值,那么说明 SQL 语句使用了临时表空间
相关参数说明
innodb_temp_tablespaces_dir
: 定义了创建 会话临时表空间的位置,默认是数据目录下的#innodb_temp 目录internal_tmp_mem_storage_engine
:定义内部临时表使用TempTable
(默认) 还是 MEMORY
。internal_tmp_disk_storage_engine
:8.0.15前可配置为innodb或myisam,8.0.16废弃,固定使用innodb。tmp_table_size
:从8.0.28开始,定义TempTable存储引擎允许创建的单个内存临时表大小,当超过该限制时,mysql会将该临时表转换成innodb引擎的磁盘临时表。temptable_max_ram
:内存表使用的内存上限,大于该值,则使用一部分磁盘映射为内存。temptable_max_mmap
:当内存使用量大于temptable_max_ram 时,MySQL 会使用 mmap 机制, 将一部分磁盘映射作为内存使用,这一部分允许的最大值即为temptable_max_mmap。总的内存临时表大小限制则由temptable_max_ram和 temptable_max_mmap控制,若tmp_table_size更大,则无法创建大于二者之和的内存临时表。 当内存临时表超过二者之和后,MySQL也会将其转换成 磁盘临时表。
temptable空间监控
select * from performance_schema.memory_summary_global_by_event_name where event_name in('memory/temptable/physical_ram','memory/temptable/physical_disk')