如何改进 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;