带有“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()用法以及效率差异

SQL Server 查询:SELECT 1 WHERE EXISTS vs SELECT TOP 1 1

使用 SQL Where Exists() 过滤结果

MySQL WHERE EXISTS 不工作