简体   繁体   English

显式连接与隐式连接?

[英]Explicit JOINs vs Implicit joins?

My Database Professor told us to use:我的数据库教授告诉我们使用:

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

Rather than:而不是:

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

Supposedly Oracle don't likes JOIN-Syntaxes, because these JOIN-syntaxes are harder to optimize than the WHERE restriction of the Cartesian Product.据说 Oracle 不喜欢 JOIN 语法,因为这些 JOIN 语法比笛卡尔积的 WHERE 限制更难优化。

I can't imagine why this should be the case.我无法想象为什么会这样。 The only Performance issue could be that the parser Needs to parse a few characters more.唯一的性能问题可能是解析器需要再解析几个字符。 But that is negligible in my eyes.但这在我眼里是微不足道的。

I found this Stack Overflow Questions:我发现了这个堆栈溢出问题:

And this sentence in a Oracle Documentation: https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries006.htm而这句话在 Oracle 文档中: https : //docs.oracle.com/cd/B19306_01/server.102/b14200/queries006.htm

Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operator. Oracle 建议您使用 FROM 子句 OUTER JOIN 语法而不是 Oracle 连接运算符。

Can someone give me up-to-date recommendations from Oracle with link.有人可以通过链接向我提供来自 Oracle 的最新建议。 Because she don't acknowledges StackOverflow (here can answer everyone) and the 10g Documentation is outdated in here eyes.因为她不承认 StackOverflow(这里可以回答每个人)并且 10g 文档在这里眼中已经过时了。

If i am wrong and Oracle realy don't likes JOINS now than thats also ok, but i don't find articles.如果我错了,而且 Oracle 现在真的不喜欢 JOINS,那也没关系,但我找不到文章。 I just want to know who is Right.我只想知道谁是对的。

Thanks a lot to everyone who can help me!非常感谢所有可以帮助我的人!

Your professor should speak with Gordon Linoff, who is a computer science professor at Columbia University.您的教授应该与哥伦比亚大学计算机科学教授 Gordon Linoff 交谈。 Gordon, and most SQL enthusiasts on this site, will almost always tell you to use explicit join syntax. Gordon 和该站点上的大多数 SQL 爱好者几乎总是会告诉您使用显式连接语法。 The reasons for this are many, including (but not limited to):造成这种情况的原因很多,包括(但不限于):

  • Explicit joins make it easy to see what the actual join logic is.显式连接可以很容易地看到实际的连接逻辑是什么。 Implicit joins, on the other hand, obfuscate the join logic, by spreading it out across both the FROM and WHERE clauses.另一方面,隐式连接通过将连接逻辑分散到FROMWHERE子句中来混淆连接逻辑。
  • The ANSI 92 standard recommends using modern explicit joins, and in fact deprecated the implicit join which your professor seems to be pushing ANSI 92 标准建议使用现代显式连接,实际上弃用了您的教授似乎正在推动的隐式连接

Regarding performance, as far as I know, both versions of the query you wrote would be optimized to the same thing under the hood.关于性能,据我所知,您编写的查询的两个版本都将在后台优化为相同的内容。 You can always check the execution plans of both, but I doubt you would see a significant difference very often.您可以随时检查两者的执行计划,但我怀疑您是否会经常看到显着差异。

An average sql query you will encounter in real business has 7-8 joins with 12-16 join conditions.您在实际业务中会遇到的平均 sql 查询有 7-8 个连接和 12-16 个连接条件。 One every 10 or 20 queries may involve nested joins or other more advanced cases.每 10 或 20 个查询可能涉及嵌套连接或其他更高级的情况。 Explicit join syntax is simply far easier to maintain, debug and develop.显式连接语法更易于维护、调试和开发。 And those factors are critical for business software - the faster and safer the better.而这些因素对商业软件至关重要——越快越安全越好。 Implicit join are somewhat easier to code if you create statements dynamically through application code.如果您通过应用程序代码动态创建语句,则隐式连接更容易编码。 Perhaps there are other uses that i am unaware.也许还有我不知道的其他用途。

As with many non-trivial things there is no simple yes / no answer.与许多重要的事情一样,没有简单的是/否答案。

The first thing is, for trivial queries (as yours example in the question) it doesn't matter which syntax you use .第一件事是,对于琐碎的查询(如问题中的示例),使用哪种语法并不重要 The classic syntax is even more compact for simple queries.对于简单的查询,经典语法更加紧凑。

First for non-trivial queries (say more than five joins) you will learn the benefits of the ANSI syntax .首先对于重要的查询(比如超过五个连接),您将了解ANSI 语法好处 The main benefit is that the join predicates are separated and divided from the WHERE condition.主要的好处是连接谓词与 WHERE 条件分开。

Simple example – this is a complete valid query in the pre-ANSI syntax简单示例——这是一个使用 ANSI 之前的语法的完整有效查询

SELECT A.a1, B.b1 
FROM A, B 
WHERE A.a1 = B.b1 and
      A.a1 = B.b1(+);

Is it inner or outer join?是内连接还是外连接? Furthermore if this construct is scattered in a predicate with 10 other join condition in the WHERE clause, it is even very easy to misread it.此外,如果这个结构散布在 WHERE 子句中有 10 个其他连接条件的谓词中,甚至很容易误读它。

Anyway, it would be very naïve to assume that those two syntax options are only a syntax sugar and that the resulting execution plan is for all queries, any data and all Oracle versions identical .无论如何,假设这两个语法选项只是语法糖,并且结果执行计划适用于所有查询、任何数据和所有 Oracle 版本都相同,那将是非常幼稚的

Yes, and there were times (about Oracle 10) you should be careful.是的,有时(关于 Oracle 10)你应该小心。 But in times of 12 and 18 versions I do not see a reason to be defensive and I'm convinced it is safe to use the ANSI syntax from the above reason of better overview and readability.但是在 12 和 18 版本的时代,我认为没有理由进行防御,并且我确信使用 ANSI 语法是安全的,因为上述原因具有更好的概述和可读性。

Final remark for your professor: if you get in the position of optimizing the WHERE restriction of the Cartesian Product you typically encounters a performance problem.给教授的最后一句话:如果您处于优化笛卡尔积的 WHERE 限制的位置,您通常会遇到性能问题。 Make a thought experiment with a Cartesian Product of four tables with 1.000 rows each…用四个表的笛卡尔积进行思想实验,每个表有 1.000 行……

There are rare occasions when the optimiser suffers from a bug when using the explicit JOIN syntax as opposed to the implicit one.在使用显式 JOIN 语法而不是隐式语法时,优化器在极少数情况下会遇到错误。 For example, I once could not achieve to profit from a join elimination optimisation in Oracle 12c when using explicit joins, whereas the join was properly eliminated with the implicit join syntax.例如,我曾经在使用显式连接时无法从 Oracle 12c 中的连接消除优化中获利,而使用隐式连接语法正确消除了连接。 When working with views querying views querying views, lack of join elimination can indeed cause performance issues.当使用视图查询视图查询视图时,缺少连接消除确实会导致性能问题。 I've explained the concept of join elimination in a blog post, here . 我已经在博客文章中解释了连接消除的概念,这里

That was a bug (and a rare one at that, these days), and not a good reason to avoid the explicit join syntax in general.那是一个错误(而且现在很少见),并且通常不是避免使用显式连接语法的好理由。 I think in current versions of Oracle, there's no reason in favour of one or the other syntax other than personal taste, when join trees are simple.我认为在当前版本的 Oracle 中,当连接树很简单时,除了个人品味之外,没有理由支持一种或另一种语法。 With complex join trees, the explicit syntax tends to be superior, as it is more clear, and some relationships (eg full outer joins or joins with complex join predicates) are not possible otherwise.对于复杂的连接树,显式语法往往更好,因为它更清晰,否则某些关系(例如完全外连接或具有复杂连接谓词的连接)是不可能的。 But neither of these arguments is about performance.但这些论点都不是关于性能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM