走進官方手冊系列 --- MySQL內部臨時表的使用
MySQL在執行語句過程中,有時會自動建立內部臨時表,而使用者無法直接干預。
MySQL一般在如下場景下會建立臨時表:
1. 含有UNION的語句
2. 使用到TEMPTABLE演算法、UNION或者兩者兼有的檢視
3. 派生表(from從句的子查詢)
4. 在做子查詢或半連線(semi-join)物化(materialization)時建立的表
5. ORDER BY和GROUP BY的從句不同;或者,ORDER BY或GROUP BY的欄位來源於除了join佇列中的第一個表之外的其他表
6. DISTINCT和ORDER BY同時使用
7. 使用到SQL_SMALL_RESULT修飾符的查詢,MySQL將會用到一個全記憶體臨時表;當查詢包含一些需要進行磁碟儲存的元素時,則會用到磁碟臨時表
8. INSERT … SELECT 語句中,如果select from和insert into的是同一張表,MySQL會建立一張內部臨時表來存放select到的行記錄,然後再將其插入到目標表中。
9. 多表UPDATE語句
10. 含有GROUP_CONCAT() 或者COUNT(DISTINCT) 函式的語句
一條語句是否用到臨時表,最簡單的辦法還是使用EXPLAIN,檢視Extra輸出中是否含有“Using temporary”。派生或實物化的臨時表,在explain過程中不一定會顯示“Using temporary”。
一旦MySQL建立了一張內部臨時表(無論是存放在記憶體中還是轉到磁碟上),都會增加Created_tmp_tables 的狀態值。如果臨時表是被建立到磁碟上(包括最初就被建立到磁碟上,以及由全記憶體錶轉換到磁碟上的),則會增加Created_tmp_disk_tables的狀態值。
如下幾種情況下,將不會使用記憶體臨時表,而會直接在磁碟上建立臨時表:
1. 表字段存在BLOB或TEXT型別。This includes user-defined variables having a string value because they are treated as BLOB or TEXT columns, depending on whether their value is a binary or nonbinary string, respectively.
2. GROUP BY或者DISTINCT子句中存在大於512bytes的字串型別的欄位;Presence of any string column in a GROUP BY or DISTINCT clause larger than 512 bytes for binary strings or 512 characters for nonbinary strings.
3. Presence of any string column with a maximum length larger than 512 (bytes for binary strings, characters for nonbinary strings) in the SELECT list, if UNION or UNION ALL is used.
4. The SHOW COLUMNS and DESCRIBE statements use BLOB as the type for some columns, thus the temporary table used for the results is an on-disk table.
5. Internal Temporary Table Storage Engine
6. Internal Temporary Table Storage Format