文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  MySQL 中內部暫存表格的使用

10.4.4 MySQL 中內部暫存表格的使用

在某些情況下,伺服器會在處理語句時建立內部暫存表格。使用者無法直接控制何時發生這種情況。

伺服器會在下列情況下建立暫存表格:

若要判斷陳述式是否需要暫存表,請使用 EXPLAIN 並檢查 Extra 欄位,查看是否顯示 Using temporary(請參閱第 10.8.1 節,使用 EXPLAIN 優化查詢)。EXPLAIN 不一定會針對衍生或具體化的暫存表顯示 Using temporary。對於使用視窗函數的陳述式,使用 FORMAT=JSONEXPLAIN 始終會提供有關視窗步驟的資訊。如果視窗函數使用暫存表,則會在每個步驟中指出。

某些查詢條件會阻止使用記憶體中的暫存表,在這種情況下,伺服器會改用磁碟上的表。

  • 表格中存在 BLOBTEXT 欄位。TempTable 儲存引擎是 MySQL 9.0 中記憶體內部暫存表的預設儲存引擎,它支援二進制大型物件類型。請參閱內部暫存表儲存引擎

  • 如果使用了 UNIONUNION ALL,則 SELECT 清單中存在任何最大長度大於 512 的字串欄位(二進制字串為位元組,非二進制字串為字元)。

  • SHOW COLUMNSDESCRIBE 陳述式將 BLOB 用作某些欄位的類型,因此用於結果的暫存表是磁碟上的表。

對於符合某些條件的 UNION 陳述式,伺服器不使用暫存表。相反,它僅保留執行結果欄位類型轉換所需之暫存表建立的資料結構。該表並未完全實例化,也沒有寫入或讀取任何列;列直接發送到用戶端。這樣做的結果是減少了記憶體和磁碟需求,並縮短了第一列發送到用戶端之前的延遲,因為伺服器不需要等到執行最後一個查詢區塊。EXPLAIN 和最佳化工具追蹤輸出反映了此執行策略:UNION RESULT 查詢區塊不存在,因為該區塊對應於從暫存表中讀取的部分。

這些條件使 UNION 符合條件,可以在不使用暫存表的情況下進行評估。

  • 聯集是 UNION ALL,而不是 UNIONUNION DISTINCT

  • 沒有全域 ORDER BY 子句。

  • 聯集不是 {INSERT | REPLACE} ... SELECT ... 陳述式的頂層查詢區塊。

內部暫存表儲存引擎

內部暫存表可以保存在記憶體中,並由 TempTableMEMORY 儲存引擎處理,或由 InnoDB 儲存引擎儲存在磁碟上。

記憶體內部暫存表的儲存引擎

internal_tmp_mem_storage_engine 變數定義了用於記憶體內部暫存表的儲存引擎。允許的值為 TempTable(預設值)和 MEMORY

注意

設定 internal_tmp_mem_storage_engine 的會話設定需要 SESSION_VARIABLES_ADMINSYSTEM_VARIABLES_ADMIN 權限。

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 儲存引擎在開始從記憶體對應檔案分配空間,或在 MySQL 開始使用 InnoDB 磁碟上的內部暫存表之前,可以使用的最大 RAM 量,具體取決於您的組態。預設的 temptable_max_ram 設定值為伺服器上可用總記憶體的 3%,預設最小值和最大值範圍為 1-4 GB。在 MySQL 8.4 之前,預設值為 1GiB。

    注意

    temptable_max_ram 設定不考慮分配給每個使用 TempTable 儲存引擎之執行緒的執行緒本地記憶體區塊。執行緒本地記憶體區塊的大小取決於執行緒的首次記憶體配置請求的大小。如果請求小於 1MB(大多數情況下都是如此),則執行緒本地記憶體區塊大小為 1MB。如果請求大於 1MB,則執行緒本地記憶體區塊的大小大致與初始記憶體請求的大小相同。執行緒本地記憶體區塊會保存在執行緒本地儲存中,直到執行緒退出。

  • temptable_use_mmap:控制當超過 temptable_max_ram 限制時,TempTable 儲存引擎是從記憶體對應檔案分配空間,還是 MySQL 使用 InnoDB 磁碟上的內部暫存表。預設設定為 temptable_use_mmap=OFF

    注意

    temptable_use_mmap 變數已過時;預期在未來版本的 MySQL 中會移除對它的支援。設定 temptable_max_mmap=0 等同於設定 temptable_use_mmap=OFF

  • temptable_max_mmap:設定在 MySQL 開始使用 InnoDB 磁碟上的內部暫存表之前,TempTable 儲存引擎允許從記憶體對應檔案分配的最大記憶體量。預設設定為 0(停用)。此限制旨在解決記憶體對應檔案在暫存目錄 (tmpdir) 中使用過多空間的風險。temptable_max_mmap = 0 會停用從記憶體對應檔案分配,有效地停用它們的使用,無論 temptable_use_mmap 設定為何。

TempTable 儲存引擎使用記憶體對應檔案受以下規則約束

  • 暫存檔案會在 tmpdir 變數定義的目錄中建立。

  • 暫存檔案會在建立和開啟後立即刪除,因此不會保留在 tmpdir 目錄中。當暫存檔案開啟時,暫存檔案佔用的空間會由作業系統保留。當 TempTable 儲存引擎關閉暫存檔案,或關閉 mysqld 程序時,會回收該空間。

  • 資料永遠不會在 RAM 和暫存檔案之間、RAM 內部或暫存檔案之間移動。

  • 如果空間在 temptable_max_ram 定義的限制內可用,則新資料會儲存在 RAM 中。否則,新資料會儲存在暫存檔案中。

  • 如果將表格的部分資料寫入暫存檔後,RAM 中有可用空間,則剩餘的表格資料有可能會儲存在 RAM 中。

當對記憶體內暫存表格使用 MEMORY 儲存引擎時(internal_tmp_mem_storage_engine=MEMORY),如果記憶體內暫存表格變得過大,MySQL 會自動將其轉換為磁碟上的表格。記憶體內暫存表格的最大大小由 tmp_table_sizemax_heap_table_size 值(以較小者為準)定義。這與使用 CREATE TABLE 明確建立的 MEMORY 表格不同。對於這類表格,只有 max_heap_table_size 變數決定表格可以增長到多大,並且不會轉換為磁碟格式。

磁碟內部暫存表格的儲存引擎

MySQL 9.0 僅對磁碟上的內部暫存表格使用 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 的值。如果太多內部暫存表格在磁碟上建立,請考慮調整內部暫存表格儲存引擎中描述的引擎特定限制。

注意

由於已知限制,Created_tmp_disk_tables 不會計算在記憶體對應檔案中建立的磁碟暫存表格。預設情況下,TempTable 儲存引擎溢位機制會在記憶體對應檔案中建立內部暫存表格。請參閱內部暫存表格儲存引擎

可以使用 memory/temptable/physical_rammemory/temptable/physical_disk Performance Schema 工具來監控 TempTable 從記憶體和磁碟配置的空間。memory/temptable/physical_ram 會報告已配置的 RAM 量。memory/temptable/physical_disk 會報告當記憶體對應檔案用作 TempTable 溢位機制時,從磁碟配置的空間量。如果 physical_disk 工具報告的值不是 0,且記憶體對應檔案用作 TempTable 溢位機制,則表示在某個時間點已達到 TempTable 記憶體限制。可以在 Performance Schema 記憶體摘要表格(例如 memory_summary_global_by_event_name)中查詢資料。請參閱第 29.12.20.10 節,「記憶體摘要表格」