在Postgres中创建索引的最有效方法

44 postgresql indexing performance

在加载数据完成之后或之前创建索引是否更有效,或者无关紧要?

例如,假设我有500个文件要加载到Postgres 8.4 DB中.以下是我可以使用的两个索引创建方案:

  1. 创建表时创建索引,然后将每个文件加载到表中; 要么
  2. 在将所有文件加载到表中后创建索引.

表数据本身大约为45千兆字节.该指数约为12千兆字节.我正在使用标准索引.它是这样创建的:

CREATE INDEX idx_name ON table_name (column_name);
Run Code Online (Sandbox Code Playgroud)

我的数据加载使用COPY FROM.

一旦加载了所有文件,表格上就不会发生更新,删除或额外加载(这是一天不会改变的数据).所以我想问哪种情况最有效?初始测试似乎表明加载所有文件然后创建索引(方案2)更快,但我没有对这两种方法进行科学比较.

mvp*_*mvp 74

您的观察是正确的 - 首先加载数据然后再创建索引要高效得多.原因是插入期间的索引更新很昂贵.如果在所有数据都存在之后创建索引,则速度会快得多.

它甚至更进一步 - 如果您需要将大量数据导入现有索引表,首先删除现有索引,导入数据,然后再次重新创建索引通常更有效.

导入后创建索引的一个缺点是该表必须被锁定,这可能需要很长时间(在相反的情况下不会被锁定).但是,在PostgreSQL 8.2及更高版本中,您可以使用CREATE INDEX CONCURRENTLY,它在索引期间不会锁定表(有一些警告).

  • 通常,新制作的45 Gigabyte表在索引之前几乎没用.锁定无用的表是没有损失的,所以尽可能快地获取索引. (24认同)
  • "*当桌子被锁定时,没有人可以读或写*" - 我不认为这是真的.当一个`CREATE INDEX`正在运行时,仍然可以读取该表,但如果我没有弄错,则不会更新. (5认同)
  • @mat_boy我在这里已经晚了2年,但是对于懒惰......当同时创建索引时,PostgreSQL将对表执行两次扫描,每次扫描必须等待已修改表的现有事务终止.这将导致索引创建需要更长时间,并且需要更多的cpu使用,导致在创建索引时对此数据库的查询速度变慢. (5认同)
  • 哪些警告?你可以解释吗? (2认同)