使用连接更新许多行非常慢
Update of many rows with join extremely slow
我有一个包含五个相关字段的 table - id
、source
、iid
、track_hash
、alias
。我想将所有条目分组到具有共同 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
语法实际上提供了 albums
到 best
:
的隐式连接
UPDATE albums AS a
SET alias = b.bid
FROM best AS b
WHERE a.track_hash = b.track_hash
我有一个包含五个相关字段的 table - id
、source
、iid
、track_hash
、alias
。我想将所有条目分组到具有共同 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
语法实际上提供了 albums
到 best
:
UPDATE albums AS a
SET alias = b.bid
FROM best AS b
WHERE a.track_hash = b.track_hash