postgresql中的long UPDATE

Nic*_*ard 6 sql postgresql sql-update

我一直在一个包含2.5亿行和3个索引的表上运行UPDATE; 此UPDATE使用另一个包含3000万行的表.现在已经运行了大约36个小时.我想知道如果他们计划花费一百万天来完成它的事情,他们是否有办法找出完成的距离,我会杀了它; 但如果它只需要一两天,我会让它运行.这是命令查询:

UPDATE pagelinks SET pl_to = page_id
    FROM page
    WHERE 
        (pl_namespace, pl_title) = (page_namespace, page_title)
        AND
        page_is_redirect = 0
;
Run Code Online (Sandbox Code Playgroud)

EXPLAIN不是这里的问题,我只提到大表有多个索引,以便在某种程度上证明更新它需要多长时间.但无论如何这里是EXPLAIN:

Merge Join  (cost=127710692.21..135714045.43 rows=452882848 width=57)
  Merge Cond: (("outer".page_namespace = "inner".pl_namespace) AND ("outer"."?column4?" = "inner"."?column5?"))
  ->  Sort  (cost=3193335.39..3219544.38 rows=10483593 width=41)
        Sort Key: page.page_namespace, (page.page_title)::text
        ->  Seq Scan on page  (cost=0.00..439678.01 rows=10483593 width=41)
              Filter: (page_is_redirect = 0::numeric)
  ->  Sort  (cost=124517356.82..125285665.74 rows=307323566 width=46)
        Sort Key: pagelinks.pl_namespace, (pagelinks.pl_title)::text"
        ->  Seq Scan on pagelinks  (cost=0.00..6169460.66 rows=307323566 width=46)
Run Code Online (Sandbox Code Playgroud)

现在我还发送了一个并行查询命令,以便DROP一个pagelinks的索引; 当然它正在等待UPDATE完成(但我觉得无论如何都要尝试它!).因此,我无法从页面链接中选择任何内容,以免损坏数据(除非您认为杀死DROP INDEX postmaster进程是安全的?).

所以我想知道它们是否是一个可以跟踪死元组数量的表,因为知道UPDATE在完成任务时有多快或多远都会很好.

Thx(PostgreSQL并不像我想象的那么聪明;它需要启发式)

Bil*_*win 5

您是否阅读了“使用 EXPLAIN ”的 PostgreSQL 文档来解释您显示的输出?

我不是普通的 PostgreSQL 用户,但我只是阅读了该文档,然后与EXPLAIN您显示的输出进行了比较。您的UPDATE查询似乎没有使用索引,并且它被迫进行表扫描以对page和进行排序pagelinks。排序无疑大到需要临时磁盘文件,我认为这些文件是在您的temp_tablespace.

然后我看到估计读取的数据库页面。该EXPLAIN输出的顶层表示(cost=127710692.21..135714045.43). 这里的单位是磁盘 I/O 访问。因此,它将访问磁盘超过 1.35 亿次来执行此操作UPDATE

请注意,即使是具有 5ms 寻道时间的 10,000rpm 磁盘,在最佳条件下也最多可实现每秒 200 次 I/O 操作。这意味着您UPDATE将需要 188 小时(7.8 天)的磁盘 I/O,即使您可以在这段时间内维持饱和的磁盘 I/O(即连续读/写没有中断)。这是不可能的,我希望实际吞吐量至少下降一个数量级,特别是因为您毫无疑问在此期间一直在使用该服务器进行各种其他工作。所以我猜你只是通过你的UPDATE.

如果是我,我会在第一天终止这个查询,并找到另一种UPDATE更好地利用索引并且不需要磁盘排序的执行方式。您可能无法在单个 SQL 语句中完成。

至于你的DROP INDEX,我猜它只是阻塞,等待对表的独占访问,当它处于这种状态时,我认为你可能会杀死它。