我最近在ORACLE DB中创建了这个脚本来更新我刚刚创建的列上的所有现有值。然而,我被告知exists函数非常慢,我应该使用update使用join代替。不幸的是,我很难找到有用的例子和/或如何在ORACLE DB中正确执行的信息。
UPDATE appeal app
SET app.is_initial = (CASE WHEN EXISTS(SELECT 1
FROM appeal app_sub
JOIN event_person ep ON app_sub.id = ep.appeal_id
JOIN event ON ep.event_id = event.id
WHERE event.name_code = 'INITIAL' AND app.id = app_sub.id)
THEN 1 ELSE 0 END)
WHERE app.is_initial IS NULL;
字符串
如果有人知道如何做到这一点,我将非常感谢的帮助。PS。我已经改变了安全表的名称。
3条答案
按热度按时间vmjh9lq91#
您可以使用
left join
尝试Merge
:字符串
7cjasjjr2#
EXISTS
不一定很慢,但也有可能很慢。这里有几点需要检查:你有
app.id
,event_person.appeal_id
和event.id
的索引吗?除非甲骨文重写这一点,标准的EXISTS
子查询将使用嵌套循环,您需要对连接列进行正确的索引,以使其性能良好。只需确保这些索引到位,就可能解决您的问题,而无需重写SQL。如果您有一个小数据集,我建议你这么做。但是,对于非常大的卷,使用
MERGE
通常可以获得更好的性能,这使您能够使用更有效的并行和直接路径扫描以及散列连接来组装数据以驱动更新。在大多数情况下,它通常不会使用索引。它看起来像这样(过度暗示只是为了说明这一点(并确保),这些提示中的大多数可能是不必要的)。字符串
(我不知道
name_code
来自哪个表;确保它没有被索引,或者如果是,确保Oracle没有使用该索引,并添加FULL([table])
提示以防止它这样做。最后,对于非常大的卷,最佳方法是根本不更新,而是创建一个新表并替换旧表:
型
创建新的段总是比更新表的每一行快得多,也更有效。如果表很小,不值得额外的步骤,但如果你谈论的是数亿或数十亿行,这是你最有效的方法。
o7jaxewo3#
假设
name_code
在event
或event_person
表中,那么您似乎不需要在子查询中使用APPEAL
,并且可以将其简化为:字符串
或者:
型
fiddle