How MySQL Manages Internal Temporary Tables
During the execution of complex queries involving operations like
GROUP BY, DISTINCT, or UNION,
MySQL often needs to create internal temporary tables to hold
intermediate result sets. This article explores how MySQL manages these
temporary tables, detailing how it transitions between in-memory and
on-disk storage, the specific storage engines involved, and the
configuration parameters that control their behavior.
Why MySQL Creates Internal Temporary Tables
MySQL automatically creates internal temporary tables when a query cannot be resolved in a single pass. Common SQL clauses and scenarios that trigger this behavior include:
- Using
GROUP BYorORDER BYon columns from different tables. - Combining
DISTINCTwithORDER BY. - Using the
UNIONorUNION DISTINCToperator. - Evaluating complex subqueries or derived tables.
- Executing certain window functions and join operations.
These tables are strictly internal, meaning they are created, managed, and dropped automatically by the MySQL server without user intervention.
In-Memory vs. On-Disk Storage
To maximize performance, MySQL always attempts to create internal temporary tables in memory first. In-memory tables offer extremely fast read and write operations. However, if the intermediate dataset becomes too large or contains data types that cannot be stored efficiently in memory, MySQL will seamlessly convert the temporary table to an on-disk table.
In-Memory Storage Engines
In modern versions of MySQL (8.0 and later), the server utilizes two primary engines for in-memory temporary tables:
- TempTable Engine (Default): Introduced in MySQL
8.0, this is the default engine. It is highly optimized and supports
efficient storage of variable-length columns (
VARCHAR,VARBINARY) and large objects (BLOB,TEXT). - MEMORY Engine: This is the legacy in-memory engine.
It uses fixed-length row formats, which can lead to high memory
consumption if the table contains wide
VARCHARcolumns.
On-Disk Storage Engines
If an in-memory temporary table exceeds its designated size limits, MySQL automatically converts it to an on-disk table.
In MySQL 8.0, the InnoDB storage engine is used to manage on-disk internal temporary tables. InnoDB provides robust performance and handles transactional overhead efficiently. Historically, MySQL used the MyISAM engine for this purpose, but InnoDB has replaced it to ensure better performance and consistency.
Triggering the Transition to Disk
The transition from an in-memory temporary table to an on-disk temporary table is governed by specific thresholds:
- For the TempTable Engine: If the memory consumed by
the TempTable engine exceeds the limit defined by the
temptable_max_ramvariable (default is 1 GB), MySQL begins spilling the data to disk. It does this either by using memory-mapped files or by converting the table directly to an InnoDB on-disk table, depending on thetemptable_use_mmapconfiguration. - For the MEMORY Engine: If the table size exceeds
the lower value of either the
tmp_table_sizeormax_heap_table_sizesystem variables, MySQL converts the in-memory table into an InnoDB on-disk table.
Additionally, in older MySQL versions, the presence of certain
columns (like BLOB or TEXT types) would
immediately force the use of an on-disk table. In MySQL 8.0, the
TempTable engine can store these types in memory, reducing the need for
premature disk I/O.
Optimizing Temporary Table Management
Database administrators can optimize the performance of queries requiring temporary tables by adjusting key system variables:
temptable_max_ram: Increase this value if your server has abundant RAM and you want to prevent complex queries from spilling to disk.tmp_table_sizeandmax_heap_table_size: Raise these limits in tandem if your queries rely on the legacy MEMORY engine for temporary tables.- Query Indexing: The most effective optimization is
often to avoid temporary tables altogether. Designing proper indexes for
GROUP BYandORDER BYoperations allows the optimizer to retrieve data in the required order without generating intermediate tables.