为什么删除索引比创建它需要更长的时间?

Mar*_*ney 11 postgresql indexing concurrency

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

当我去掉索引时,我让它运行> 200秒而不返回,最后取消了放下操作.

CREATE INDEX idx_cservicelocationdivisionstatus_inversed
ON cservicelocationdivisionstatus (cservicelocationdivisionid, startdate, enddate DESC);
Run Code Online (Sandbox Code Playgroud)

花很少的时间,但是

DROP INDEX idx_cservicelocationdivisionstatus_inversed;
Run Code Online (Sandbox Code Playgroud)

花了这么长时间才放弃并取消了.

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

为什么删除索引所需的时间比创建索引要长得多?

编辑:此页面指示对于mySql,具有多个索引的表将复制表并重新插入所有行而不删除您正在删除的索引.(更糟糕的是,使用mySql,如果你在同一个表上删除多个索引,它将为你要删除的每个索引重新复制一次表,而不是聪明并重新复制数据一次而不是所有的索引你是这样的事情会发生在postgres吗?

kha*_*son 22

您提到的表格上的索引通常应该能够很快被删除(当然比3分钟更快).听起来像表/索引正在使用中,因此无法删除.

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

  • DROP INDEX CONCURRENTLY可能是该问题的另一个快速解决方案. (5认同)
  • 我的问题是,巨大的桌子正在执行自动清理,因此它被阻塞,直到完成为止。这是一个“同时删除索引”,但这对于它被阻止没有任何影响。 (4认同)
  • 这就是问题所在。有一个长时间运行的查询(> 20分钟)正在使用该表。我杀死查询后,删除索引花了51毫秒。 (3认同)
  • @Ben:很高兴它适合你的情况。Postgres 在这里不返回错误/消息的原因是,这不是错误/边缘情况,而是预期的锁定行为。如果存在实际的死锁——请参阅 https://www.postgresql.org/docs/current/static/explicit-locking.html 中的“13.3.4 死锁”部分以获取更多信息——Postgres 会检测到这一点并提供一个异常消息。 (2认同)