在 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 ... INTO
或 CREATE 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
是多余的。
我创建了一个 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 ... INTO
或 CREATE 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
是多余的。