文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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

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

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

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

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

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

  • 表格中存在 BLOBTEXT 資料行。在 MySQL 8.4 中,用於記憶體內部暫存表格的預設儲存引擎 TempTable 支援二進位大型物件類型。請參閱內部暫存表格儲存引擎

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

以下規則控制 TempTable 儲存引擎對記憶體對應檔案的使用

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

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

  • 資料永遠不會在 RAM 和暫存檔案之間、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 8.4 僅使用 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 效能綱要工具來監控從記憶體和磁碟配置的 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 節,「記憶體摘要表」