PostgreSQL:如果聚集索引已经存在,新索引的 CREATE INDEX 是否更快?

PostgreSQL: is CREATE INDEX faster for new indexes if a clustered index already exists?

我的问题是关于数据加载过程中的性能。我需要在 16 亿行 table 上创建四个索引,我想知道以下哪一个更快:

  1. 正在创建一个索引,对其进行聚类,然后创建其他索引:

    CREATE INDEX i_col1 ON db.tbl USING btree (col1);
    CLUSTER db.tbl USING i_col1;
    CREATE INDEX i_col2 ON db.tbl USING btree (col2);
    CREATE INDEX i_col3 ON db.tbl USING btree (col3);
    CREATE INDEX i_col4 ON db.tbl USING btree (col4);
    
  2. 创建所有索引,然后对相同的第一个索引进行聚类:

    CREATE INDEX i_col1 ON db.tbl USING btree (col1);
    CREATE INDEX i_col2 ON db.tbl USING btree (col2);
    CREATE INDEX i_col3 ON db.tbl USING btree (col3);
    CREATE INDEX i_col4 ON db.tbl USING btree (col4);
    CLUSTER db.tbl USING i_col1;
    

索引就像……索引!想一想一本书的索引,它指定了书页的内容。因此索引将向 Postgres 指出该特定数据在磁盘上的位置。

当您执行 CLUSTER 操作时,Postgres 将物理重组 磁盘中的数据。

因此,根据该信息,选项 1 是最快的。看,如果在创建剩余的 3 个索引之前对数据进行集群,数据在磁盘中的距离会更近,这将使 Postgres 更容易找到它需要的数据,从而使索引创建更快。

但是,请留出一些时间考虑您是否真的 需要同一个 table 中的所有这些索引。太多的索引可能比根本没有索引更糟糕。引用 Postgres documentation:

Indexes are primarily used to enhance database performance (though inappropriate use can result in slower performance).

此外,我不应该回答你的 VACUUM 问题,因为这不是本主题的主题,但最好在 CREATE INDEX 之前执行 VACUUM,因为 VACUUM 会删除所有死元组,因此,在创建索引时要迭代的垃圾就会更少。查看 this link 了解有关 VACUUM 过程的更多信息。