【问题标题】:Replacing NOT IN with NOT EXISTS and an OUTER JOIN in Oracle Database 12c在 Oracle Database 12c 中用 NOT EXISTS 和 OUTER JOIN 替换 NOT IN
【发布时间】:2018-01-13 14:50:45
【问题描述】:

我知道,当我们使用 EXISTS 和 NOT EXISTS 代替 IN 和 NOT IN 时,我们的查询性能得到了提高,但是,当我们用 OUTER JOIN 代替 NOT EXISTS 时,性能是否会进一步提高?

例如,以下查询从 PRODUCT 表中选择不在另一个名为 PC 的表中的所有模型。作为记录,PRODUCT 或 PC 表中的模型值都不是空值:

select model
from product
where not exists(
select * 
from pc
where product.model = pc.model);

以下 OUTER JOIN 将显示相同的结果:

select product.model
from product left join pc
on pc.model = product.model
where pc.model is null;

鉴于它们都返回相同的值,我们应该使用哪个选项来更好地提高查询性能?

【问题讨论】:

  • 两者应该是一样的。 Oracle 有一个很好的优化器,这两种方式都是半反连接的表达方式。
  • “我知道当我们使用 EXISTS 和 NOT EXISTS 代替 IN 和 NOT IN 时,我们的查询性能会得到提高”。在某些情况下。在其他情况下,IN 或 NOT IN 表现更好。性能取决于驱动查询和子查询的相对大小。

标签: oracle outer-join not-exists


【解决方案1】:

查询计划会告诉你。这将取决于数据和表格。在 OUTER JOIN 和 NOT EXISTS 的情况下,它们是相同的。

但是,对于您的开场白,如果模型上接受 NULL,则 NOT IN 和 NOT EXISTS 是不一样的。在这种情况下,您说模型不能为空,因此您可能会发现它们都有相同的计划。但是,在做出这个假设时,必须告诉数据库不能有空值(使用 NOT NULL),而不是根本没有空值。如果您不这样做,它将为每个查询制定不同的计划,这可能会根据您的实际数据导致不同的性能。这通常是正确的,尤其是对于不索引 NULL 的 ORACLE。

查看解释计划

【讨论】:

  • 无论列是否为NULL,查询都会产生相同的结果集。他们很可能有相同的执行计划。因此,它们很可能完全相同。
  • 是同意,如果数据中没有空值,结果将是相同的。但是,如果有空值,它们将是不同的结果。 DB 需要知道 NULL 不是一个选项,否则 EXISTS 和 IN 将不会生成相同的计划,即使我们知道结果将是相同的。
  • NOT EXISTSLEFT JOIN/WHERE IS NULL 完全相同。您可能会将其与 NOT INNOT EXISTS 混淆,其中 NULL 的处理方式不同。
  • 是的 - 我指的是不存在/不存在。为了清楚起见,我会更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
  • 2014-12-29
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多