在 PostgreSQL 中聚集索引是否利用了预先排序的数据?

Does clustering an index in PostgreSQL take advantage of preordered data?

我创建了一个 table 像这样:

SELECT t1.c1, t2.c2, t3.c3, *several more columns*
INTO t4
FROM t1
INNER JOIN t2 ON t1.j2 = t2.j2
INNER JOIN t3 ON t1.j3 = t3.j3;

然后,我创建一个集群主键:

ALTER TABLE t4 ADD CONSTRAINT pk_t4 PRIMARY KEY (c1, c2, c3);
CLUSTER t4 USING pk_t4;

如果我在 SELECT INTO 查询中添加一个 ORDER BY c1, c2, c3 子句,是否会加快主键的聚类速度?

如果您使用 SELECT ... INTOCREATE TABLE AS SELECT ... 创建新的 table,PostgreSQL 将按顺序插入记录。

因此,是的,如果您添加一个 ORDER BY c1, c2, c3,这也是一个主键,它们将已经被聚类,因此不需要 CLUSTER

但是,如果您再次 运行 集群,我认为 PostgreSQL 将重写 table。


例子

首先生成一个 table 具有 500 万个整数,随机顺序:

testdb=> create table clust as select a from generate_series(1, 5000000) a order by random() ;
SELECT 5000000
Time: 14675,540 ms
testdb=> create index clust_a_idx on clust (a);
CREATE INDEX
Time: 13145,245 ms
testdb=> cluster clust using clust_a_idx;
CLUSTER
Time: 19126,597 ms
testdb=> cluster clust using clust_a_idx;
CLUSTER
Time: 7968,350 ms

第一次聚类需要 19 秒,第二次需要 7.9 秒。

创建另一个table,这次已经订购了:

testdb=> create table clust2 as select a from generate_series(1, 5000000) a ;
SELECT 5000000
Time: 2612,878 ms
testdb=> create index clust2_a_idx on clust2 (a);
CREATE INDEX
Time: 6816,040 ms
testdb=> cluster clust2 using clust2_a_idx;
CLUSTER
Time: 7762,115 ms
testdb=> cluster clust2 using clust2_a_idx;
CLUSTER
Time: 7861,405 ms

聚类已经排序table聚类大约需要 7.8 秒。

ORDER BY c1, c2, c3有帮助吗? 是。

但是如果您以正确的顺序插入,table 已经排序(成簇)并且 CLUSTER 是多余的。