tmp_table_size 和 max_heap_table_size MySQL 屬性的經驗法則
標題幾乎總結了這個問題本身:關於MySQL 屬性的值是否
tmp_table_size
有經驗法則?max_heap_table_size
我有一個嚴重的性能下降,這是由於 MySQL 使用磁碟空間來對 JOIN 結果進行文件排序。
增加
tmp_table_size
和max_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_size
、read_buffer_size
和其他緩衝區的記憶體)或您將生成的最大臨時表,無論哪個更小。您可以使用
Created_tmp_disk_tables
和Created_tmp_tables
變數來了解您在全域範圍內創建了多少臨時表和磁碟上的臨時表(儘管有些是不可避免的 - 例如,堆表不允許 blob,有些查詢將始終需要臨時表,沒有重要的索引)。