PostgreSQL VACUUM FULL 和 CLUSTER 的區別
我有一個表,其上的 6 個索引佔用了 200 GB 的數據大小和 180 GB 的大小。它膨脹了 30%,所以我想回收它佔用的不需要的空間。它聚集在
job_id_id
x 索引上。那麼要回收空間,我需要使用
cluster
命令還是vacuum full
命令?
- 這兩個命令有什麼區別?
vacuum full
某些列的順序與cluster
命令相同嗎?- 是否在兩個命令中都重新創建了索引?
- 在我的情況下,哪一個會更快?
PostgreSQL數據庫的版本是9.1
為了檢查是什麼
CLUSTER
,我從早期的實驗中獲取了一張表,該表基本上包含前 1000 萬個正整數。我已經刪除了一些行,還有另一列,但這些只影響實際的表大小,所以它不是那麼有趣。首先,
VACUUM FULL
在桌子上跑步後fka
,我取了它的大小:\dt+ fka List of relations Schema | Name | Type | Owner | Size | Description --------+------+-------+----------+--------+------------- public | fka | table | test | 338 MB |
然後讓我們從表的最開始看數據的物理順序:
SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5; id | col1 | ctid -----+------+--------- 2 | 2 | (0,1) 3 | 3 | (0,2) 4 | 4 | (0,3) 5 | 5 | (0,4) 6 | 6 | (0,5)
現在讓我們刪除一些行:
DELETE FROM fka WHERE id % 10 = 5; --DELETE 1000000
在此之後,報告的表大小沒有改變。所以現在讓我們看看是什麼
CLUSTER
:CLUSTER fka USING fka_pkey; SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5; id | col1 | ctid -----+------+--------- 2 | 2 | (0,1) 3 | 3 | (0,2) 4 | 4 | (0,3) 6 | 6 | (0,4) 7 | 7 | (0,5)
操作後,表大小從 338 MB 變為 296 MB。從
ctid
描述元組在頁面中的物理位置的列中,您還可以看到行匹配id = 5
過去的位置沒有間隙。隨著元組的重新排序,應該重新創建索引,以便它們指向正確的位置。
所以區別看起來是
VACUUM FULL
沒有對行進行排序。據我所知,這兩個命令使用的機制存在一些差異,但從實際的角度來看,這似乎是主要的(唯一的?)差異。
VACUUM FULL
將表的全部內容重寫到沒有額外空間的新磁碟文件中,允許將未使用的空間返回給作業系統。此方法還需要額外的磁碟空間,因為它會寫入表的新副本並且在操作完成之前不會釋放舊副本。通常這應該只在需要從表中回收大量空間時使用。http://www.postgresql.org/docs/9.1/static/sql-vacuum.html
CLUSTER
指示 PostgreSQL 根據 index_name 指定的索引對 table_name 指定的表進行分群。索引必須已經在 table_name 上定義。當一個表被聚集時,它會根據索引資訊進行物理重新排序,並在其上獲取一個 ACCESS EXCLUSIVE 鎖。http://www.postgresql.org/docs/9.1/static/sql-cluster.html
也很有趣:is-a-reindex-required-after-cluster
但也許您需要的只是一個簡單
REINDEX
的方法,它使用儲存在索引表中的數據重建索引,替換索引的舊副本。