Postgresql

PostgreSQL VACUUM FULL 和 CLUSTER 的區別

  • July 22, 2013

我有一個表,其上的 6 個索引佔用了 200 GB 的數據大小和 180 GB 的大小。它膨脹了 30%,所以我想回收它佔用的不需要的空間。它聚集在job_id_idx 索引上。

那麼要回收空間,我需要使用cluster命令還是vacuum full命令?

  1. 這兩個命令有什麼區別?
  2. vacuum full某些列的順序與cluster命令相同嗎?
  3. 是否在兩個命令中都重新創建了索引?
  4. 在我的情況下,哪一個會更快?

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的方法,它使用儲存在索引表中的數據重建索引,替換索引的舊副本。

http://www.postgresql.org/docs/9.1/static/sql-reindex.html

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