简体   繁体   English

PostgreSQL 用索引缓慢更新

[英]PostgreSQL slow update with index

Very simply update to reset 1 column in a table with approx 5mil rows as:非常简单地更新以将具有大约 500 万行的表中的 1 列重置为:

UPDATE t_Daily 
SET Price= NULL

Price is not part of any of the indexes on that table.价格不是该表中任何索引的一部分。

Running this without indexes takes 45s.在没有索引的情况下运行它需要 45 秒。

Running this with one or more indexes takes at least 20 mins (I keep having to stop it).使用一个或多个索引运行它至少需要 20 分钟(我一直不得不停止它)。

I fully understand why maintaining indexes affects the performance of insert and update statements, but this update makes no changes to the table indexes so why does it have this terrible effect on performance?我完全理解为什么维护索引会影响插入和更新语句的性能,但是这次更新不会对表索引进行任何更改,那么为什么它会对性能产生如此可怕的影响呢?

Any ideas much appreciated.任何想法都非常感谢。

Found some further info (thanks to Laurenz-Albe for the HOT tip).找到了一些进一步的信息(感谢Laurenz-Albe的热门提示)。

This link [ https://malisper.me/postgres-heap-only-tuples/] states that此链接 [ https://malisper.me/postgres-heap-only-tuples/]指出

Due to MVCC, an update in Postgres consists of finding the row being updated, and inserting a new version of the row back into the database.由于 MVCC,Postgres 中的更新包括查找正在更新的行,并将该行的新版本插入回数据库。 The main downside to doing this is the need to readd the row to every index这样做的主要缺点是需要将行读取到每个索引

So it is re-writing the index despite only updating a column not in the index.因此,尽管只更新了不在索引中的列,但它仍在重写索引。

That is normal and expected: updating an index can be about ten times as expensive as updating the table itself.这是正常和预期的:更新索引的成本可能是更新表本身的十倍左右。 The table has no ordering!桌子没有顺序!

If price is not indexed, you can use HOT updates that avoid updating the indexes.如果price未编入索引,您可以使用避免更新索引的热更新。 To make use of that, the table has to be defined with a fillfactor under 100 so that updated rows can find room in the same block as the original rows.为了利用这一点,必须使用小于 100 的fillfactor定义表,以便更新的行可以在与原始行相同的块中找到空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM