我有一个表,其中数据占用200 GB的大小,表上的6个索引占用180 GB的大小。它已膨胀了30%,所以我想回收它占用的多余空间。它聚集在job_id_id
x索引上。
所以要回收空间,我需要使用cluster
command还是vacuum full
command?
这两个命令有什么区别?
是
vacuum full
为了通过一些列相同cluster
的命令?是否在两个命令中都重新创建了索引?
就我而言,哪一个会更快?
PostgreSQL数据库版本为9.1
我有一个表,其中数据占用200 GB的大小,表上的6个索引占用180 GB的大小。它已膨胀了30%,所以我想回收它占用的多余空间。它聚集在job_id_id
x索引上。
所以要回收空间,我需要使用cluster
command还是vacuum full
command?
这两个命令有什么区别?
是vacuum full
为了通过一些列相同cluster
的命令?
是否在两个命令中都重新创建了索引?
就我而言,哪一个会更快?
PostgreSQL数据库版本为9.1
Answers:
为了检查结果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
不对行进行排序。据我所知,这两个命令使用的机制有所不同,但是从实际的角度来看,这似乎是主要的区别(仅?)。
ctid
列是什么。原来这是一个系统列,描述了表中行的物理位置。postgresql.org/docs/current/ddl-system-columns.html
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
也很有趣:集群之后需要重新索引
但也许您所需要的只是一个简单的方法REINDEX
,即使用存储在索引表中的数据重建索引,从而替换索引的旧副本。