Postgresql

功能中的 Postgres 真空

  • February 14, 2022

google了一下之後,很明顯你不能從一個函式執行vacuum:

Postgres 郵件 - plpgsql 函式中的真空行為

由於記憶體管理限制,您不能從函式內部執行 VACUUM。在目前來源中,有一個錯誤檢查以防止您嘗試。

Stackoverflow - 無法從函式或多命令字元串執行 VACUUM

載入數據後,我想對受影響的表進行“真空分析”,以從已刪除的記錄中恢復空間並準確反映新內容。

$$ … $$當我執行它時,我得到: ERROR: VACUUM cannot be executed from a function or multi-command string

但是我真的需要在執行某個函式時“自動”執行 Vacuum:這個函式會更新很多記錄(如果不是全部的話),所以死行的數量增加得很快,而其他查詢性能下降很多。問題是該函式是從另一個程序呼叫的。有什麼最佳做法嗎?我是否應該在函式執行後手動將vacuum語句添加到一段單獨的程式碼中,比如

sql = SELECT my_function() <program.execute(sql)> sql = VACUUM [FULL | ANALYZE] my_updated_table <program.execute(sql)>

文件頁面:

**提示:**由於大量更新或刪除活動導致表包含大量死行版本時,普通 VACUUM 可能無法令人滿意。如果您有這樣的表並且需要回收它佔用的多餘磁碟空間,則需要使用 VACUUM FULL,或者 CLUSTER或 ALTER TABLE 的表重寫變體之一。這些命令重寫表的全新副本並為其建構新索引。所有這些選項都需要排他鎖。請注意,它們還臨時使用大約等於表大小的額外磁碟空間,因為表和索引的舊副本在新副本完成之前無法釋放。

如果您無法在表上使用排他鎖,您也可以使用簡單的ANALYZE <tablename>;,因為它只需要一個讀鎖,並且應該更新表的統計資訊並減少(如果不是完全消除)性能下降對於其他查詢。然後你可以讓正常的 autovacuum 守護程序正常地做它的事情(或者你目前的自定義真空解決方案可能是什麼)。

如果你的表甚至沒有聚集索引,你首先需要做一個ALTER TABLE <tablename> CLUSTER ON <indexname>;. 無論如何,您可能應該擁有某種聚集索引:擁有龐大的堆表和較差的性能通常是齊頭並進的。

就最佳實踐而言,我非常傾向於推薦這種ANALYZE方法,因為到目前為止進行自動統計更新比自動索引重建或幾乎任何形式的VACUUM FULL在沒有管理員積極觀察的情況下執行更可取。

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