我有两个表:源表和目标表.目标表将包含源表的列的子集.我需要通过基于另一列连接源表来更新目标表中的单个列.更新声明如下:
UPDATE target_table tt SET special_id = ( SELECT source_special_id FROM source_table st WHERE tt.another_id = st.another_id )
出于某种原因,这种说法似乎无限期地运行.内部选择在自己执行时几乎立即发生.该表有大约50,000条记录,并且托管在一台功能强大的机器上(资源不是问题).
我这样做了吗?上述任何原因都不能及时发挥作用?有更好的方法吗?
初始查询对外部表中的每一行执行一次内部子查询.看看Oracle是否更喜欢这样:
UPDATE target_table SET special_id = st.source_special_id FROM target_table tt INNER JOIN source_table st WHERE tt.another_id = st.another_id
(在发布查询后编辑已更正)
添加: 如果连接语法不适用于Oracle,那么如何:
UPDATE target_table SET special_id = st.source_special_id FROM target_table tt, source_table st WHERE tt.another_id = st.another_id
关键是要连接两个表而不是使用当前使用的外部查询语法.
source_table(another_id)上有索引吗?如果不是source_table将在target_table中的每一行完全扫描一次.如果target_table很大,这将需要一些时间.
对于某些target_table行,source_table中是否可能没有匹配?如果是这样,您的更新将为这些行将special_id设置为null.如果你想避免这样做:
UPDATE target_table tt SET special_id = ( SELECT source_special_id FROM source_table st WHERE tt.another_id = st.another_id ) WHERE EXISTS( SELECT NULL FROM source_table st WHERE tt.another_id = st.another_id );
如果 target_table.another_id被声明为引用source_table.another_id的外键(在这种情况下不太可能),这将起作用:
UPDATE ( SELECT tt.primary_key, tt.special_id, st.source_special_id FROM tatget_table tt JOIN source_table st ON st.another_id = tt.another_id ) SET special_id = source_special_id;