使用连接更新许多行非常慢

Update of many rows with join extremely slow

我有一个包含五个相关字段的 table - idsourceiidtrack_hashalias。我想将所有条目分组到具有共同 track_hash 的组中,然后为每一行保存具有最低 source 的行的 id (打破联系以支持最高 iid) 从其组中进入 alias 字段。为此,我编写了以下查询:

with best as 
(SELECT id as bid, track_hash FROM
    (SELECT id, track_hash,
        RANK () OVER ( 
            PARTITION BY track_hash
            ORDER BY source asc, iid DESC
        ) rank
        from albums
    )
    where rank = 1
)
select bid, a.* from albums a inner join best
on a.track_hash = best.track_hash

这在 24k 行上花费了完全合理的 2 秒。现在,我不想简单地看到这个 id,而是想实际保存它。为此,我使用了以下非常相似的查询:

with best as 
(SELECT id as bid, track_hash FROM
    (SELECT id, track_hash,
        RANK () OVER ( 
            PARTITION BY track_hash
            ORDER BY source asc, iid DESC
        ) rank
        from albums
    )
    where rank = 1
)
update albums
set alias = bid FROM albums a inner join best
on a.track_hash = best.track_hash

然而,这个需要 1 到 10 分钟,我真的不明白为什么。无论如何,引擎不需要将每一行与其 best.id/alias 匹配,这正是我在更新时所做的吗?为什么会这样,我做错了什么?

查询计划如下所示:

MATERIALIZE 1
CO-ROUTINE 4
SCAN TABLE albums USING INDEX track_hash_idx
USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
SCAN SUBQUERY 4
SCAN TABLE albums USING COVERING INDEX track_hash_idx
SEARCH SUBQUERY 1 USING AUTOMATIC PARTIAL COVERING INDEX (rank=?)
SEARCH TABLE albums AS a USING COVERING INDEX track_hash_idx (track_hash=?)

您不需要加入 albums(再次)。
UPDATE ... FROM 语法实际上提供了 albumsbest:

的隐式连接
UPDATE albums AS a
SET alias = b.bid 
FROM best AS b
WHERE a.track_hash = b.track_hash