如何改进 Oracle 中的更新查询
How to improve an Update query in Oracle
我正在尝试更新陈旧的 Oracle 数据库中的两列,但查询根本没有完成,也没有更新任何内容。有什么改进查询的想法或可以做的其他事情吗?我没有 DBA skills/knowledge,不确定索引是否有帮助,因此也希望在该领域发表评论。
PERSON table:这个 table 有 2 亿个不同的 person_id。没有重复项。 person_id 是数字,我正在尝试更新 favorite_color 和 color_confidence 列,这些列是 varchar2 并且值当前为 NULLed。
person table
person_id favorite_color color_confidence many_other_columns
222
333
444
TEMP_COLOR_CONFIDENCE table:我试图从这个 [=39= 中获取 favorite_color 和 color_confidence ] 并更新为 PERSON table。这个 table 有 1.5 亿不同的人,同样没有重复。
temp_color_confidence
person_id favorite_color color_confidence
222 R H
333 Y L
444 G M
这是我的更新查询,我知道它只更新在两个 table 中找到的查询。最终我需要用“U”更新剩余的 5000 万——未知。一次解决这个问题也很理想,但目前只是担心我无法完成此查询。
UPDATE person p
SET (favorite_color, color_confidence) =
(SELECT t.favorite_color, t.color_confidence
FROM temp_color_confidence t
WHERE p.person_id = t.person_id)
WHERE EXISTS (
SELECT 1
FROM temp_color_confidence t
WHERE p.person_id = t.person_id );
这就是我无知的地方...索引person_id会有帮助吗,考虑到它们都是不同的?在 favorite_color 上建立索引会有帮助吗?不到10种颜色,只有3个置信度值。
对于每个人,它必须在temp_color_confidence中找到相应的行。用最少的 I/O 来做到这一点的方法是扫描每个 table 一次并在单个散列连接中将它们一起处理,最好全部在内存中。索引不太可能对此有所帮助,除非 temp_color_confidence 非常宽泛且冗长并且在 (person_id, favorite_color, color_confidence) 上有一个索引,优化器可以将其视为瘦 table.
使用merge
可能更有效,因为它可以避免第二次扫描temp_color_confidence:
merge into person p
using temp_color_confidence t
on (p.person_id = t.person_id)
when matched then update
set p.favorite_color = t.favorite_color, p.color_confidence = t.color_confidence;
如果您要更新 table 中的每一行,您可能会考虑创建一个新的 table 包含您需要的所有值:
create table person2
( person_id, favorite_color, color_confidence )
pctfree 0 compress
as
select p.person_id, nvl(t.favorite_color,'U'), nvl(t.color_confidence,0)
from person p
left join temp_color_confidence t
on t.person_id = p.person_id;
我正在尝试更新陈旧的 Oracle 数据库中的两列,但查询根本没有完成,也没有更新任何内容。有什么改进查询的想法或可以做的其他事情吗?我没有 DBA skills/knowledge,不确定索引是否有帮助,因此也希望在该领域发表评论。
PERSON table:这个 table 有 2 亿个不同的 person_id。没有重复项。 person_id 是数字,我正在尝试更新 favorite_color 和 color_confidence 列,这些列是 varchar2 并且值当前为 NULLed。
person table
person_id favorite_color color_confidence many_other_columns
222
333
444
TEMP_COLOR_CONFIDENCE table:我试图从这个 [=39= 中获取 favorite_color 和 color_confidence ] 并更新为 PERSON table。这个 table 有 1.5 亿不同的人,同样没有重复。
temp_color_confidence
person_id favorite_color color_confidence
222 R H
333 Y L
444 G M
这是我的更新查询,我知道它只更新在两个 table 中找到的查询。最终我需要用“U”更新剩余的 5000 万——未知。一次解决这个问题也很理想,但目前只是担心我无法完成此查询。
UPDATE person p
SET (favorite_color, color_confidence) =
(SELECT t.favorite_color, t.color_confidence
FROM temp_color_confidence t
WHERE p.person_id = t.person_id)
WHERE EXISTS (
SELECT 1
FROM temp_color_confidence t
WHERE p.person_id = t.person_id );
这就是我无知的地方...索引person_id会有帮助吗,考虑到它们都是不同的?在 favorite_color 上建立索引会有帮助吗?不到10种颜色,只有3个置信度值。
对于每个人,它必须在temp_color_confidence中找到相应的行。用最少的 I/O 来做到这一点的方法是扫描每个 table 一次并在单个散列连接中将它们一起处理,最好全部在内存中。索引不太可能对此有所帮助,除非 temp_color_confidence 非常宽泛且冗长并且在 (person_id, favorite_color, color_confidence) 上有一个索引,优化器可以将其视为瘦 table.
使用merge
可能更有效,因为它可以避免第二次扫描temp_color_confidence:
merge into person p
using temp_color_confidence t
on (p.person_id = t.person_id)
when matched then update
set p.favorite_color = t.favorite_color, p.color_confidence = t.color_confidence;
如果您要更新 table 中的每一行,您可能会考虑创建一个新的 table 包含您需要的所有值:
create table person2
( person_id, favorite_color, color_confidence )
pctfree 0 compress
as
select p.person_id, nvl(t.favorite_color,'U'), nvl(t.color_confidence,0)
from person p
left join temp_color_confidence t
on t.person_id = p.person_id;