【问题标题】:Optimizing index update speed during bulk insert into table批量插入表时优化索引更新速度
【发布时间】:2014-03-22 07:02:33
【问题描述】:

在向表中插入大量数据时(从另一个表中,不按特定顺序),如何优化多列索引,以便以最快的方式更新索引?

假设索引从未在任何SELECT、DELETE 或UPDATE 查询中使用。* 还假设列的不同计数如下(例如):

COLUMN | DISTINCT COUNT
col1   |            634
col2   |          9,923
col3   |          2,357
col4   |              3

* 在选择数据时不使用索引的原因是这是主键索引或唯一约束索引。索引已经到位,因此违反约束的插入应该会失败。

我已经读过,最有选择性的列应该放在第一位。是否正确,然后按如下方式创建索引?

(col2, col3, col1, col4)

如果这是错误的,你如何确定索引中列的最佳顺序,该索引只能看到大量INSERTs 进入相应的表?目标是在批量INSERT时加快索引的更新。

【问题讨论】:

    标签: sql postgresql indexing postgresql-9.1


    【解决方案1】:

    最快的方法是DROP INDEX,然后在插入完成后进行批量插入和CREATE INDEX。

    索引的正确结构与列中值的分布没有太大关系,而是与检索策略有关,大概只针对UPDATE和DELETE,然后特别是当您对一些但并非全部总是索引的所有列。那些更频繁的过滤器应该首先出现在您的索引列中。但如果是这种情况,您可能需要更彻底地重新考虑您的索引策略:最好有两个或更多索引来匹配您的典型检索策略。

    忽略您对无知的呼吁:您为什么不将索引应用于SELECT 语句?索引仅可用于从表中选择数据子集,无论是用于 SELECT 还是合格的 UPDATE 或 DELETE。在这三个操作中的任何一个中使用索引都没有功能上的区别。

    来自 OP 的 cmets 之后的附录:索引可用于多种用途,但它们的维护相对昂贵,随着表大小的增加,“相对”变得“不可能”很快。在您的情况下,您必须将源表中的每条记录与目标表中的每条记录或 O(m*n) 顺序进行比较。这对于大尺寸的表是行不通的,即使是索引也是如此。最好的办法是删除索引,进行插入,创建一个不唯一的索引,查找并删除所有重复项,删除索引,最后创建一个新的唯一索引.

    【讨论】:

    • 在选择数据时不使用的原因是这是主键索引或唯一约束索引。索引已经到位,因此违反约束的插入应该会失败。无论如何,感谢您的见解。删除和创建索引的速度是否比就地更新索引更快?怎么会这样?
    • 此外,现在知道索引是唯一约束,您可能会意识到删除索引并在之后创建它不是一个好主意,因为它违背了索引的目的。如何在索引就位的同时在批量插入期间优化索引更新速度?
    • 谢谢。这不是一个非常可行的解决方案,因为如果有重复,我预计整个批量插入都会失败(包括唯一插入)。但我理解您对性能的看法。
    【解决方案2】:

    列的顺序对于唯一性强制执行而言并不是非常重要。但是,唯一索引碰巧对某些查询也没有用处是不寻常的,因此我会订购列以利用这一点。

    为了快速批量插入此索引,我会尝试按索引顺序插入。因此,将order by (col2, col3, col1, col4) 添加到插入的选择部分。这会带来更高效的 IO。

    【讨论】:

    • “这会带来更高效的 IO。” 这已经验证了吗?
    • 是的。我一直都这样做。如果与加载到的表相比,批量加载太小,您不会看到太大差异。如果自上次重建后索引的大小增加了数倍,则改进将小于最近重建(尽管这比我想象的要重要)
    猜你喜欢
    • 2014-01-16
    • 2012-02-07
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 2012-11-10
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多