在 Postgresql 9.5 中的大表上创建主键的最佳方法是什么?

rkt*_*rkt 6 postgresql ddl postgresql-9.5

我必须在 Postgtres 数据库中的一个大表(约 1 亿条记录)上创建一个主键。创建 pkey 的最佳和最快方法是什么?此列是一个序列列,我不想锁定表,因为这是高度事务性的数据库。

a_h*_*ame 11

您可以使用该选项创建唯一索引,该选项concurrently将允许在创建索引时对表进行读写访问。但是,与不使用该选项的情况下添加索引相比,同时构建索引需要更长的时间。

create unique index concurrently unique_id on the_big_table (id);
Run Code Online (Sandbox Code Playgroud)

创建索引后,您可以将其用作主键:

alter table the_big_table
   add primary key using index unique_id;
Run Code Online (Sandbox Code Playgroud)

这只会在很短的时间内锁定表。


Ran*_*est 2

如果要添加主键,则必须锁定表。

但是(这将需要一些存储空间)...

  • 创建具有相同架构(以及索引、外键、检查约束等)的新表,并添加新的主键。

  • 创建一个从两个表中选择(使用 UNION ALL)的视图,并在安静时期(或维护窗口),将旧表重命名为其他名称,为视图指定与旧表相同的名称,然后您的用户和应用程序不应该知道差异(从视图而不是表中选择)。

  • 创建一个批处理,一次从旧表中删除 x 行,并将这些行插入新表中。

  • 在另一个维护窗口中,删除视图,重命名新表,以便它获得原始表名称(并且它已经具有所有索引、外键、检查约束等),然后删除旧表,现在应该是空的。

运行它需要一些时间,具体取决于您在每个批次中移动的行数,但它使您的表(现在是视图的一部分)保持在线。您将生成大量日志,并且需要相当多的磁盘空间,但这就是我要做的。