带有“where exists”的“Set”比没有的效果更好
Posted
技术标签:
【中文标题】带有“where exists”的“Set”比没有的效果更好【英文标题】:"Set" with "where exists" performs better then without 【发布时间】:2016-10-13 14:27:45 【问题描述】:我偶然发现了这个奇怪的案例。
环境:
Oracle 12.2.2 涉及 2 个表。 N. 1600 万行据我所知,并在此报告 Oracle / PLSQL: EXISTS Condition where exists
的使用通常不如其他方式。
然而,在我的情况下,当使用存在的另一个连接条件更新表的列时,查询在大约 12-13 秒内运行而没有问题(我只做了一些检查,因为我真的不知道所有表的内容):
update fdm_auftrag ou
set (ou.e_hr,ou.e_budget) = ( select b.e_hr,b.e_budget
from fdm_budget_auftrag b
where b.fk_column1 = ou.fk_column1
and b.fk_column2 = ou.fk_column2
and b.fk_col3 = ou.fk_col3 )
where exists ( select b.e_hr,b.e_budget
from fdm_budget_auftrag b
where b.fk_column1 = ou.fk_column1
and b.fk_column2 = ou.fk_column2
and b.fk_col3 = ou.fk_col3 );
如果没有存在,它会花费很多时间然后我什至打断它。
我只是在猜测,因为存在的条件被评估为布尔值,如果工程师发现至少一行,那么就必须减少对数据库的接触,但我不确定。
这个“猜测”是正确的,有人解释清楚吗?
【问题讨论】:
此外,您链接到的文章根本不正确。相关子查询不必对驱动表中的每一行执行一次,优化器可以使用哈希半连接非常有效地完成此操作。 【参考方案1】:where
子句限制更新的行数。
更新的行越少意味着update
查询运行得更快。更新行会产生很多开销,包括为了回滚而隐藏信息。
我假设您在一个更大的表中更新相对较少的行。如果where
子句选择了大部分行,那么可能没有性能差异。
最后,这两个查询并不相同。如果没有where
,不匹配的值将被分配NULL
。
【讨论】:
感谢您的快速答复。我不确定为什么这 2 个查询是不同的,为什么不存在引擎分配“Null”值,因为它必须仅在设置条件下更新列值。此外,两个子查询的条件相同 经过几次检查后,我认为如果没有“存在”条件,则会在不匹配的行上使用空值进行更新。谢谢@Gordon Linoff以上是关于带有“where exists”的“Set”比没有的效果更好的主要内容,如果未能解决你的问题,请参考以下文章
带有 WHERE EXISTS 的 SQL UPDATE 语句
Oracle where exists 子句不适用于 SQL Plus
Oracle-where exists()not exists() in()not in()用法以及效率差异