【问题标题】:Most Efficient Way to Create an Index in Postgres在 Postgres 中创建索引的最有效方法
【发布时间】:2013-09-05 23:44:53
【问题描述】:

是在加载数据完成之后还是之前创建索引更高效,还是没关系?

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

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

表数据本身约为 45 GB。该索引约为 12 GB。我正在使用标准索引。它是这样创建的:

CREATE INDEX idx_name ON table_name (column_name);

我的数据加载使用COPY FROM

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

【问题讨论】:

    标签: performance postgresql indexing


    【解决方案1】:

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

    更进一步 - 如果您需要将大量数据导入现有的索引表,通常先删除现有索引,导入数据,然后重新创建索引更有效。

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

    【讨论】:

    • 好吧,当表被锁定时,没有人可以读取或写入,这可能非常烦人,即使在晚上也是如此。你最好同时使用 CREATE INDEX
    • 当表被锁定时,没有人可以读取或写入” - 我不认为这是真的。当CREATE INDEX 运行时,表格仍然可以读取,但如果我没记错的话不会更新。
    • 通常一个新创建的 45 GB 表在被索引之前几乎没有用处。锁定一个无用的表是没有损失的,所以尽快完成索引。
    • 有哪些注意事项?你能解释一下吗?
    • @mat_boy 我在这里迟到了大约 2 年,但是对于懒惰的人来说......同时创建索引时,PostgreSQL 将对表执行两次扫描,每次扫描都必须等待已存在的事务修改表以终止。这将导致创建索引需要更长的时间,并且需要更多的 cpu 使用,从而导致在创建索引时对该数据库的查询速度变慢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-22
    • 2011-12-22
    相关资源
    最近更新 更多