我有一个包含约 210 万行的 Postgres 表。我对其进行了以下更新:
WITH stops AS (
SELECT id,
rank() OVER (ORDER BY offense_timestamp,
defendant_dl,
offense_street_number,
offense_street_name) AS stop
FROM consistent.master
WHERE citing_jurisdiction=1
)
UPDATE consistent.master
SET arrest_id=stops.stop
FROM stops
WHERE master.id = stops.id;
Run Code Online (Sandbox Code Playgroud)
这个查询运行了 39 个小时。我在一个 4(物理)核心 i7 Q720 笔记本电脑处理器上运行它,有足够的内存,绝大多数时间没有其他东西运行。没有硬盘空间限制。该表最近已被清空、分析和重新索引。
在查询运行的整个过程中,至少在初始WITH
完成之后,CPU 使用率通常很低,并且 HDD 使用 100%。硬盘的使用非常用力,以至于任何其他应用程序的运行速度都比正常情况慢得多。
笔记本电脑的电源设置为高性能(Windows 7 x64)。
这是解释:
Update on master (cost=822243.22..1021456.89 rows=2060910 width=312)
CTE stops
-> WindowAgg (cost=529826.95..581349.70 rows=2060910 width=33)
-> Sort (cost=529826.95..534979.23 rows=2060910 width=33)
Sort Key: consistent.master.offense_timestamp, consistent.master.defendant_dl, consistent.master.offense_street_number, consistent.master.offense_street_name …
Run Code Online (Sandbox Code Playgroud) 某些更新在大型 Postgres 表上花费的时间太长。鉴于这些条件:
...您可能会认为,相对于使用 Bitlocker 旋转媒体的预期,更新将花费合理的时间。我们不会创建更多数据,因此不需要在 HDD 上移动现有数据,只需覆盖它即可。其他索引应该不需要更改。等等,相反,经过20个小时不断的硬盘磨练,我厌倦了等待,停止了查询。如果我删除其他列上的所有索引并重新运行查询,则只需要大约 30 分钟。
为什么与此查询无关的列上的索引会使更新时间膨胀?