【问题标题】:Oracle SQL Query Filter in JOIN ON vs WHEREJOIN ON 与 WHERE 中的 Oracle SQL 查询过滤器
【发布时间】:2014-10-09 09:56:41
【问题描述】:

对于内连接,在JOIN ON 子句或WHERE 子句中应用过滤器的性能有什么不同吗?哪个效率更高,或者优化器会使它们相等?

加入

SELECT u.name
FROM users u
JOIN departments d
ON u.department_id = d.id
AND d.name         = 'IT'

VS

在哪里

SELECT u.name
FROM users u
JOIN departments d
ON u.department_id = d.id
WHERE d.name       = 'IT'

Oracle 11gR2

【问题讨论】:

  • 测试每种方法时发生了什么?
  • 应该没什么区别。您可以随时使用EXPLAIN PLAN FOR 查看计划或使用dbms_xplan 函数查看实际执行计划。
  • 在测试时,它们似乎是相同的,但我的理解是你会从中受益,包括加入过滤器(某种预过滤器)
  • 查询引擎在执行查询之前自己进行优化。
  • 这确实是问题的重复,“Inner join vs Where”,stackoverflow.com/questions/121631/inner-join-vs-where?rq=1

标签: sql performance oracle inner-join where


【解决方案1】:

应该没有区别。优化器应该在这两种情况下生成相同的计划,并且应该能够在任何一种情况下根据对该特定查询最有效的方法在连接之前、之后或期间应用谓词。

当然,优化器可以做某事的事实,一般来说,并不能保证优化器在特定查询中实际做某事。随着查询变得越来越复杂,不可能详尽地考虑每一个可能的查询计划,这意味着即使有完美的信息和完美的代码,优化器也可能没有时间做你想做的所有事情。您需要查看为这两个查询生成的实际计划,看看它们是否实际上相同。

【讨论】:

  • 此外,在WHERE 子句中连接表包含关于 SQL89 的旧式语法。从 SQL92 及更高版本开始,鼓励使用 JOIN 语法以提高可读性,而不是为了性能,因为它们应该执行相同,具体取决于其复杂性。
  • @WillMarcouiller - 我认为没有人在谈论将连接谓词放在WHERE 子句中,而不是使用 SQL99 连接语法。这个问题只是关于将过滤谓词放在 join 子句而不是 WHERE 子句中。当然,Oracle 采用 SQL99 连接语法相对较晚,并且解析器的前几个版本存在一些错误,导致旧式语法更有效,至少有时是这样。这在 11.2 中可能不是什么大问题,但它确实让一些人对新语法感到不满。
【解决方案2】:

我更喜欢将过滤条件放在where 子句中。

对于数据仓库查询,将过滤条件放在联接中似乎会导致查询持续时间显着延长。

例如,我有 Table1 按字段 DateTable2 由字段 Partition 分区。 Table2 是查询中最大的表,位于另一个数据库服务器中。我使用 driving_site 提示告诉优化器使用 Table2 分区。

select /*+driving_site(b)*/ a.key, sum(b.money) money
  from schema.table1 a
  join schema2.table2@dblink b
    on a.key = b.key
 where b.partition = to_number(to_char(:i,'yyyymm'))
   and a.date = :i
 group by a.key`

如果我这样查询,返回结果大约需要 30-40 秒。

如果我不以这种方式进行查询,大约需要 10 分钟才能取消执行而没有结果。

【讨论】:

    猜你喜欢
    • 2017-12-21
    • 1970-01-01
    • 2021-05-03
    • 2019-02-15
    • 2022-12-06
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    相关资源
    最近更新 更多