Mysql

tmp_table_size 和 max_heap_table_size MySQL 屬性的經驗法則

  • December 17, 2018

標題幾乎總結了這個問題本身:關於MySQL 屬性的值是否tmp_table_size有經驗法則?max_heap_table_size

我有一個嚴重的性能下降,這是由於 MySQL 使用磁碟空間來對 JOIN 結果進行文件排序。

增加tmp_table_sizemax_heap_table_size到 3G 解決了這個問題,但這更多是一種試錯法。

有沒有更可靠的方法來計算這兩者的適當值?

我建議為每一個簡單的 1% 的記憶體。

  • max_heap_table_size``ENGINE=MEMORY是你表上的極限CREATE。沒有多少人使用該引擎,如果您這樣做,請在創建之前設置最大大小。
  • LEAST(max_heap_table_size, tmp_table_size)是讓某些隱式臨時表獲得多大的上限。這些是在SELECTs(etc) 內部用來處理GROUP BY, ORDER BY, 子查詢等的表。

由於每個連接都可以創建這些臨時表,並且每​​個查詢可能創建多個臨時表,因此 1% 的 RAM 是一個相當“安全”的限制。當 MySQL 用完 RAM 時,作業系統會交換東西——交換 MySQL 對性能來說是很糟糕的。

此外,如果將這些設置得太大,您會從其他用途(例如 buffer_pool)中竊取 RAM,從而可能會減慢所有查詢的速度。

其他經驗法則

另請參閱SQL_BIG_RESULT

盡可能長時間地增加tmp_table_size(及其依賴性, IF MEMORY 用於臨時記憶體引擎 - 最新版本使用 InnoDB)可能很誘人。max_heap_table_size畢竟,如果您使用更大的表大小執行相同的查詢,它可能會更快!

但是,有兩個理由不這樣做,我能想到:

  • 如果臨時表很大,您將浪費時間將行插入記憶體,然後將其複製到磁碟,然後繼續插入行。根據查詢,您可能會發現盡快寫入磁碟可能會更快。
  • 雖然設置大緩衝區似乎是個好主意,但記憶體並不是無限的——因此,如果每個查詢/連接都將佔用 3G 記憶體,您可能會用完它,並且由於虛擬記憶體交換而開始寫入磁碟(這可能會由於記憶體不足錯誤而導致 MySQL 崩潰,或者速度非常慢)。

現在,如果您只執行一個查詢而不是幾個並發查詢(因此您不會遇到這些問題),並且它可以讓您更快,請隨意增加它(但可能您可能想要更改它會話,所以它不會影響可能得到我提到的那些回歸的其他查詢)。

要計算一個好的值,請選擇您希望查詢佔用的最大記憶體量(注意,您還需要用於join_buffer_size. sort_buffer_sizeread_buffer_size和其他緩衝區的記憶體)或您將生成的最大臨時表,無論哪個更小。

您可以使用Created_tmp_disk_tablesCreated_tmp_tables變數來了解您在全域範圍內創建了多少臨時表和磁碟上的臨時表(儘管有些是不可避免的 - 例如,堆表不允許 blob,有些查詢將始終需要臨時表,沒有重要的索引)。

引用自:https://dba.stackexchange.com/questions/209411