【问题标题】:Why does dropping an index take longer than creating it?为什么删除索引比创建索引需要更长的时间?
【发布时间】:2014-12-08 09:09:18
【问题描述】:

在 postgresql 中,我为一个大表添加了一个索引,大约花了 1 秒(坦率地说,这让我感到惊讶)。

我去drop索引的时候,让它运行了>200秒没有返回,最后取消了drop操作。

CREATE INDEX idx_cservicelocationdivisionstatus_inversed
ON cservicelocationdivisionstatus (cservicelocationdivisionid, startdate, enddate DESC);

花费很少的时间,但是

DROP INDEX idx_cservicelocationdivisionstatus_inversed;

花了这么长时间,我放弃并取消了。

cservicelocationdivisionstatus 表有 6 列和大约 310k 行数据。

为什么删除索引比创建索引要花这么长时间?

编辑:This page 表示对于 mySql,具有多个索引的表将复制该表并重新插入所有行,而无需删除您要删除的索引。 (更糟糕的是,使用 mySql,如果您在同一个表上删除多个索引,它将为您要删除的每个索引重新复制一次表,而不是在没有所有索引的情况下聪明地重新复制一次数据下降。) postgres 是否会发生这种情况?

【问题讨论】:

标签: postgresql indexing concurrency


【解决方案1】:

您提到的大小的表上的索引通常应该能够很快被删除(当然比 3 多分钟更快​​)。在我看来,表/索引正在使用中,因此无法删除。

您可以通过查询pg_stat_activity 表并查找涉及您创建索引的表的活动来确认这一点。

【讨论】:

  • 这就是问题所在。有一个长时间运行的查询(>20 分钟)正在使用该表。一旦我终止查询,删除索引需要 51 毫秒。
  • 啊。 51ms 听起来更像。 =)
  • 同时删除索引可能是该问题的另一个快速解决方法。
  • @kert:它对 drop 本身的时间没有太大帮助,但它会影响其他访问器。它消除了对独占锁的需求,并且本质上为访问者提供了在删除完成之前完成的机会。但它也有一些警告(specifics here)
  • @Ben:很高兴它对您的情况有用。 Postgres 在这里没有返回错误/消息的原因是这不是错误/边缘情况,而是预期的锁定行为。如果存在实际死锁——请参阅postgresql.org/docs/current/static/explicit-locking.html 中的“13.3.4 死锁”部分了解更多信息——Postgres 会检测到该情况并提供异常消息。
猜你喜欢
  • 2011-01-29
  • 1970-01-01
  • 2015-11-03
  • 2010-12-18
  • 2020-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多