臨時文件和 work_mem
我的 Postgres 實例正在記錄如下內容:
2021-11-16 22:18:52.491 UTC [1808765]: [3-1] db=xxx,user=xxx LOG: temporary file: path "base/pgsql_tmp/pgsql_tmp1808765.0", size 262144
我的理解是,如果
work_mem
太低,Postgres 可以使用臨時文件進行排序。但是如果我執行show work_mem;
,我會看到目前值為 86000kB,這比我在日誌中看到的臨時文件的大小要大得多。還有什麼我應該在這裡看的嗎?
請務必了解該
work_mem
設置的實際作用。手冊:
work_mem
(integer
)在寫入臨時磁碟文件之前,設置查詢操作(例如排序或雜湊表)使用的基本最大記憶體量。如果此值指定為不帶單位,則以千字節為單位。預設值為四兆字節 (
4MB
)。請注意,對於復雜的查詢,可能會並行執行多個排序或散列操作;在開始將數據寫入臨時文件之前,通常允許每個操作使用此值指定的記憶體量。此外,幾個正在執行的會話可以同時執行此類操作。因此,使用的總記憶體可能是值的許多倍work_mem
;在選擇值時必須牢記這一事實。排序操作用於ORDER BY
,DISTINCT
, 並合併連接。雜湊表用於雜湊連接、基於雜湊的聚合、結果記憶體節點和基於雜湊的 IN 子查詢處理。基於雜湊的操作通常比等效的基於排序的操作對記憶體可用性更敏感。可用於雜湊表的記憶體是通過乘以 來計算
work_mem
的hash_mem_multiplier
。這使得基於散列的操作可以使用超過通常work_mem
基本數量的記憶體量。(
hash_mem_multiplier
在 Postgres 13 中添加。)如果 Postgres 需要的記憶體超出
work_mem
任何給定操作所允許的範圍,它就會開始溢出到磁碟。所以你觀察到的是多餘的:我看到目前值為 86000kB,比我在日誌中看到的臨時文件的大小要大得多。
將您的
work_mem
設置(至少)增加觀察到的臨時文件的大小,它應該會消失。但是,也不要設置
work_mem
得太高,因為這可能會耗盡記憶體和並發事務。work_mem
對於異常大的操作,人們總是可以在本地設置一個更高的值。看: