Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Internal Temporary Table Use in MySQL

10.4.4 MySQL 中的内部临时表使用

在某些情况下,服务器在处理语句时创建内部临时表。用户无法直接控制何时发生这种情况。

服务器在以下情况下创建临时表:

要确定语句是否需要临时表,请使用 EXPLAIN 并检查 Extra 列,以查看是否说 Using temporary(见 第 10.8.1 节,“使用 EXPLAIN 优化查询”)。 EXPLAIN 不一定说 Using temporary 对于派生或物化临时表。对于使用窗口函数的语句,EXPLAIN with FORMAT=JSON 始终提供窗口步骤信息。如果窗口函数使用临时表,则在每个步骤中都将其指示。

某些查询条件会阻止使用内存临时表,在这种情况下,服务器将使用磁盘表代替:

  • 表中存在 BLOBTEXT 列。 TempTable 存储引擎是 MySQL 8.3 中内存临时表的默认存储引擎,支持二进制大对象类型。见 内部临时表存储引擎

  • 表中存在任何字符串列,最大长度超过 512(二进制字符串的字节,非二进制字符串的字符)在 SELECT 列表中,如果使用 UNIONUNION ALL

  • SHOW COLUMNSDESCRIBE 语句使用 BLOB 作为某些列的类型,因此临时表用于结果是磁盘表。

服务器不使用临时表来满足某些条件的 UNION 语句。相反,它仅保留临时表创建所需的数据结构,以执行结果列类型转换。该表不完全实例化,也不会写入或从中读取行;行直接发送到客户端。结果是减少了内存和磁盘需求,并且在发送第一行到客户端之前的延迟减少,因为服务器不需要等待最后一个查询块执行完毕。EXPLAIN 和优化器跟踪输出反映了这种执行策略:UNION RESULT 查询块不存在,因为该块对应于从临时表读取的部分。

这些条件使 UNION 语句无需临时表:

  • 该union是 UNION ALL,而不是 UNIONUNION DISTINCT

  • 没有全局 ORDER BY 子句。

  • 该union不是 {INSERT | REPLACE} ... SELECT ... 语句的顶级查询块。

内部临时表存储引擎

内部临时表可以在内存中保存并由 TempTableMEMORY 存储引擎处理,也可以由 InnoDB 存储引擎在磁盘上保存。

内存中内部临时表的存储引擎

变量 internal_tmp_mem_storage_engine 定义了在内存中内部临时表的存储引擎。允许的值是 TempTable(默认)和 MEMORY

存储引擎 TempTable 提供了对 VARCHARVARBINARY 列的高效存储,以及其他二进制大对象类型。

以下变量控制 TempTable 存储引擎的限制和行为:

  • tmp_table_size:定义了由 TempTable 存储引擎创建的任何单个内存内部临时表的最大大小。当 tmp_table_size 限制达到时,MySQL 会自动将内存内部临时表转换为 InnoDB 磁盘内部临时表。默认的 tmp_table_size 设置是 16777216 字节(16 MiB)。

    限制 tmp_table_size 是为了防止单个查询消耗过多的全局 TempTable 资源,这可能会影响并发查询的性能,这些查询需要 TempTable 资源。全局 TempTable 资源由 temptable_max_ramtemptable_max_mmap 设置控制。

    如果tmp_table_size限制小于temptable_max_ram限制,那么内存临时表不能包含超过tmp_table_size限制的数据。如果tmp_table_size限制大于temptable_max_ramtemptable_max_mmap限制的总和,那么内存临时表不能包含超过temptable_max_ramtemptable_max_mmap限制的总和。

  • temptable_max_ram:定义TempTable存储引擎可以使用的最大RAM量,超过该限制后,TempTable存储引擎将从内存映射文件中分配空间或使用InnoDB磁盘内部临时表,具体取决于您的配置。默认temptable_max_ram设置为1073741824字节(1GiB)。

    Note

    The temptable_max_ram设置不包括每个线程的线程本地内存块大小,该大小取决于线程的初始内存分配请求。如果请求小于1MB,通常情况下,线程本地内存块大小为1MB。如果请求大于1MB,线程本地内存块大小约等于初始内存请求大小。线程本地内存块在线程退出时释放。

  • temptable_use_mmap:控制TempTable存储引擎是否从内存映射文件中分配空间或使用InnoDB磁盘内部临时表,当temptable_max_ram限制被超过时。默认设置为temptable_use_mmap=ON

    Note

    The temptable_use_mmap变量已弃用;预计在未来版本的MySQL中删除对其的支持。设置temptable_max_mmap=0等同于设置temptable_use_mmap=OFF

  • temptable_max_mmap:设置TempTable存储引擎从内存映射文件中分配的最大空间量,超过该限制后,MySQL将使用InnoDB磁盘内部临时表。默认设置为1073741824字节(1GiB)。该限制旨在解决临时目录(tmpdir)中的内存映射文件使用太多空间的风险。temptable_max_mmap = 0禁用从内存映射文件的分配,无论temptable_use_mmap设置如何。

TempTable存储引擎使用内存映射文件的规则如下:

  • 临时文件在tmpdir变量定义的目录中创建。

  • 临时文件在创建和打开后立即删除,因此不再tmpdir目录中可见。临时文件占用的空间由操作系统持有,直到临时文件被TempTable存储引擎关闭或mysqld进程关闭时释放。

  • 数据从不在RAM和临时文件之间、RAM内部或临时文件之间移动。

  • 新的数据存储在 RAM 中,如果在定义的限制内有可用的空间,定义由 temptable_max_ram。否则,新的数据将存储在临时文件中。

  • 如果在 RAM 中有可用的空间可用来存储表数据的一部分,然后将剩余的表数据存储在 RAM 中。

使用 MEMORY 存储引擎的内存临时表(internal_tmp_mem_storage_engine=MEMORY),MySQL 会自动将内存临时表转换为磁盘表,如果表变得太大。内存临时表的最大大小由 tmp_table_sizemax_heap_table_size 值定义,取较小的那个值。这与使用 MEMORY 存储引擎显式创建的表不同,对于这些表,只有 max_heap_table_size 变量确定表可以增长的大小,并且没有转换为磁盘格式。

磁盘内部临时表的存储引擎

MySQL 8.3 只使用 InnoDB 存储引擎来存储磁盘内部临时表。(MYISAM 存储引擎不再支持这种用途。)

InnoDB 磁盘内部临时表是在会话临时表空间中创建的,默认情况下位于数据目录中。有关更多信息,请参阅 第 17.6.3.5 节,“临时表空间”

内部临时表存储格式

当内存内部临时表由 TempTable 存储引擎管理时,包含 VARCHAR 列、VARBINARY 列和其他二进制大对象类型列的行将在内存中表示为单元格数组,每个单元格包含一个 NULL 标志、数据长度和数据指针。列值将连续存储在单个内存区域中,不带填充。每个单元格使用 16 字节的存储空间。相同的存储格式也适用于 TempTable 存储引擎从内存映射文件中分配空间时。

当内存内部临时表由 MEMORY 存储引擎管理时,固定长度行格式将被使用。VARCHARVARBINARY 列值将被填充到最大列长度,以便存储它们作为 CHARBINARY 列。

磁盘内部临时表总是由 InnoDB 管理的。

使用 MEMORY 存储引擎时,语句可以最初创建一个内存内部临时表,然后如果表变得太大,将其转换为磁盘表。在这种情况下,可能会通过跳过转换并从一开始就在磁盘上创建内部临时表来提高性能。big_tables 变量可以用于强制磁盘存储内部临时表。

监控内部临时表创建

当内部临时表在内存或磁盘上创建时,服务器将增加 Created_tmp_tables 值。当内部临时表在磁盘上创建时,服务器将增加 Created_tmp_disk_tables 值。如果在磁盘上创建了太多内部临时表,考虑调整引擎特定的限制,如 内部临时表存储引擎 中所述。

Note

由于已知的限制,Created_tmp_disk_tables 不会统计在内存映射文件中创建的磁盘临时表。默认情况下,TempTable 存储引擎溢出机制会在内存映射文件中创建内部临时表。请参阅 内部临时表存储引擎

可以使用 memory/temptable/physical_rammemory/temptable/physical_disk 性能架构仪表来监控 TempTable 空间分配来自内存和磁盘。memory/temptable/physical_ram 报告分配的 RAM 数量。memory/temptable/physical_disk 报告从磁盘分配的空间大小,当使用内存映射文件作为 TempTable 溢出机制时。如果 physical_disk 仪表报告的值不是 0,并且使用内存映射文件作为 TempTable 溢出机制,那么在某个时候达到了 TempTable 内存限制。可以在性能架构内存摘要表中查询数据,例如 memory_summary_global_by_event_name。请参阅 第 29.12.20.10 节,“内存摘要表”