【问题标题】:PostgreSQL select a frequently updated row from a small tablePostgreSQL 从一个小表中选择一个经常更新的行
【发布时间】:2018-01-04 11:57:02
【问题描述】:

我使用的是 PostgreSQL 9.6 (Ubuntu 16.04),我有一个大约 10k 行的小表 T,其中每行在高峰时间每分钟更新 2 次(类似于UPDATE T SET c1 = ?, c2 = ? WHERE id = ?)。此外,这是在该表中完成的唯一更新操作,并且插入和删除根本不经常。

但是,我注意到 T 中的 SELECT 查询有点慢,经过一番研究,我发现 "an update in PostgreSQL is actually a transaction of DELETE+INSERT (due MVCC)" .此外,我发现了类似的问题,例如 this onethis one,但与 UPDATE 查询有关。

我的问题是:连续频繁更新会减慢选择查询的速度吗?如果是这样,正确的处理方法是什么?

【问题讨论】:

  • 这取决于选择的内容。索引中的更新列是否用作选择的条件?查询计划说明了什么?
  • 你可以在一段时间后使用 VACUUM 来保持性能
  • @SamiKuhmonen:更新的列不在索引中,也不用作选择的条件,尽管在其中一个查询中有这些列之一的排序。我想非索引列的频繁更新比索引列好,对吧?关于查询计划,我会用EXPLAIN ANALYZE的结果更新问题
  • 很大程度上取决于完整的表定义、事务处理、您通常运行的确切查询以及您的 autovacuum 设置。 [postgresql-performance] 问题需要更多细节。请参阅标签信息中的说明。

标签: postgresql postgresql-performance vacuum autovacuum


【解决方案1】:

是的,正如您所说,频繁更新/删除可能是查询缓慢的原因。 因为,任何已删除的行(无论是实际的 DELETE 还是从 UPDATE 中删除)都只是标记为删除,并且实际上保留在数据页中,直到它用于另一个插入。为避免这种情况,您应该在桌子上运行适当的维护例程,例如 VACUUM。 另一个简单的解决方案是,

create table similar_table;

insert into similar_table;

select * from original_table;

drop original_table;

alter table rename similar_table original_table;

这可以用于小表而不是使用 VACUUM。

您还应该查看查询计划。糟糕的查询也会使选择变慢。

【讨论】:

    【解决方案2】:

    如果某行被删除或更新,旧版本会被自动清理进程自动清理并重新使用空间。如果您只更新非索引列,则“删除/插入”部分实际上根本不会发生(称为“HOT - 仅堆元组”更新)。

    使用较小的fillfactor 创建表可能是个好主意,以便在数据库块上留出空间来存储“新”行(您可能想尝试 60% 或 70% 之类的东西)

    “频繁”更新通常只有在它们过于频繁以至于自动清理无法跟上,或者如果您有太多并发和打开的事务以至于自动清理无法释放任何空间时才会出现问题。很多时候,这可以通过提高自动真空度来缓解。

    无论如何,通过索引列进行单行查找的查询不太可能受到频繁更新的影响。 如果您确实看到速度变慢,那么您可能需要定期reindex 表。

    【讨论】:

      猜你喜欢
      • 2017-02-23
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 2015-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      相关资源
      最近更新 更多