显式联接与隐式联接?

时间:2018-10-30 09:49:59

标签: database oracle performance join

我的数据库教授告诉我们使用:

SELECT A.a1, B.b1 FROM A, B WHERE A.a2 = B.b2;

而不是:

SELECT A.a1, B.b1 FROM A INNER JOIN B ON A.a2 = B.b2;

据说Oracle不喜欢JOIN语法,因为这些JOIN语法比笛卡尔乘积的WHERE限制更难优化。

我无法想象为什么会这样。唯一的性能问题可能是解析器需要再解析几个字符。但这在我看来微不足道。

我发现了此堆栈溢出问题:

Oracle文档中的这句话:https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries006.htm

  

Oracle建议您使用FROM子句OUTER JOIN语法而不是Oracle join运算符。

有人可以通过链接给我来自Oracle的最新建议吗?因为她不承认StackOverflow(在这里可以回答所有人),并且10g文档在这里已经过时了。

如果我错了,Oracle真的不喜欢JOINS,那也可以,但是我找不到文章。我只想知道谁是正确的。

非常感谢能帮助我的每个人!

4 个答案:

答案 0 :(得分:10)

您的教授应与哥伦比亚大学计算机科学教授Gordon Linoff交谈。 Gordon和该站点上的大多数SQL爱好者几乎总是会告诉您使用显式联接语法。造成这种情况的原因很多,包括(但不限于):

  • 显式联接使您可以轻松了解实际的联接逻辑。另一方面,隐式联接通过在FROMWHERE子句中散布联接逻辑来模糊联接逻辑。
  • ANSI 92标准建议使用现代显式联接,实际上已弃用了您的教授似乎在推动的隐式联接

就性能而言,据我所知,您编写的查询的两个版本都将在后台优化为同一件事。您始终可以检查两者的执行计划,但是我怀疑您会经常看到很大的不同。

答案 1 :(得分:2)

您在实际业务中会遇到的平均sql查询具有7-8个联接和12-16个联接条件。每10或20个查询之一可能涉及嵌套连接或其他更高级的情况。 显式连接语法更容易维护,调试和开发。这些因素对于商业软件至关重要-越快越安全越好。 如果通过应用程序代码动态创建语句,则隐式连接的编码会更容易一些。也许还有其他我不知道的用途。

答案 2 :(得分:2)

对于许多不重要的事情,没有简单的是/否答案。

第一件事是,对于琐碎的查询(例如您在问题中的示例),使用哪种语法都没关系。对于简单的查询,经典语法更加紧凑。

首先进行非平凡查询(例如,五个以上的联接),您将学到 ANSII语法的优点。主要好处是连接谓词与WHERE条件分开并分开。

简单的示例–这是使用ANSII之前的语法的完整有效查询

{
  "total_count": 0,
  "incomplete_results": false,
  "items": [

  ]
}

是内部联接还是外部联接?此外,如果将此 construct 分散在WHERE子句中具有其他10个连接条件的谓词中,则很容易会误读它。

无论如何,假设这两个语法选项只是一个语法糖并且执行计划天真对于所有查询,任何数据和所有Oracle版本相同

是的,而且有时(关于Oracle 10)您应该小心。但是在12和18版本中,我看不出有防御的理由,并且我说服了ANSII语法是安全的,因为上面的原因具有更好的概述和可读性。

给您教授的最后一句话:如果您优化笛卡尔乘积的WHERE限制,通常会遇到性能问题。用四个表(每个表有1.000行)的笛卡尔积做一个思维实验

答案 3 :(得分:0)

在使用显式 JOIN 语法而不是隐式语法时,优化器在极少数情况下会遇到错误。例如,我曾经在使用显式连接时无法从 Oracle 12c 中的连接消除优化中获利,而使用隐式连接语法正确消除了连接。当使用视图查询视图查询视图时,缺少连接消除确实会导致性能问题。 I've explained the concept of join elimination in a blog post, here

那是一个错误(而且现在很少见),并且通常不是避免使用显式连接语法的好理由。我认为在当前版本的 Oracle 中,当连接树很简单时,除了个人品味之外,没有理由支持一种或另一种语法。对于复杂的连接树,显式语法往往更好,因为它更清晰,并且某些关系(例如完全外部连接或具有复杂连接谓词的连接)是不可能的。但这些争论都与性能无关。