18

我正在研究内部连接,我是 WHERE SQL-92 的老男人。我想知道其中的含义并了解它是如何工作的。所以这只是一个关于 SQL 连接的理论问题。这是...

 SELECT * FROM   -- Query 1
 tbl1
 INNER JOIN (
          tbl2 
          INNER JOIN (
             tbl3 INNER JOIN tbl4 ON tbl3.Col1 = tbl4.Col1 
          ) 
          ON tbl2.col1 = tbl3.col2
 ) 
 ON tbl1.col1 = tbl3.col3

……和这个一样吗?

 SELECT * FROM   -- Query 2
 tbl3 
 INNER JOIN tbl4 ON tbl3.col1 = tbl4.col1
 INNER JOIN tbl2 ON tbl2.col1 = tbl3.col2
 INNER JOIN tbl1 ON tbl1.col1 = tbl3.col3

...或者这个(不按逻辑分辨率排序)?

  SELECT * FROM   -- Query 3
  tbl3 
  INNER JOIN tbl1 ON tbl1.col1 = tbl3.col3
  INNER JOIN tbl2 ON tbl2.col1 = tbl3.col2
  INNER JOIN tbl4 ON tbl3.col1 = tbl4.col1

..or this(参考节点已更改;请参阅在引用之前引用了一个表,但笛卡尔积应该是相同的)

  SELECT * FROM   -- Query 4
  tbl4 
  INNER JOIN tbl1 ON tbl1.col1 = tbl3.col3
  INNER JOIN tbl2 ON tbl2.col1 = tbl3.col2
  INNER JOIN tbl3 ON tbl4.col1 = tbl3.col1

..或这个?

  SELECT * FROM   -- Query 5 
  tbl1,tbl2,tbl3,tbl4
  WHERE 
  tbl3.col1 = tbl4.col1
  tbl2.col1 = tbl3.col2
  tbl1.col1 = tbl3.col3

...从美学、句法、最佳实践和功能的角度来看?

这是一个非常开放的问题,但我认为社区提供一些启发非常有趣!

4

3 回答 3

13

我一直密切合作的所有数据库引擎(即SQL Server, Oracle, PostgreSQL, MySQL, Sybase, SQLite,InformixFirebird)都会将其优化为相同的计划。

然而,第四个查询不会在所有引擎上解析(在ON子句中使用表之前,您不能在子句中引用表JOIN

MySQL提供STRAIGHT_JOIN影响计划中使用的连接顺序的子句。

Oracle,有一个提示/*+ ORDERED */,在SQL Server有一个类似的提示FORCE ORDER。如果查询使用这些提示,则计划顺序也会受到连接顺序的影响。

于 2012-04-26T13:53:07.160 回答
3

从正确性的角度来看,它们可能是相等的。从性能的角度来看,它取决于 RDBMS(我只能说 SQL Server,所有变体都会产生相同的执行计划)。

于 2012-04-26T13:39:15.547 回答
1

在 Sybase 中,它们也将具有相同的执行计划!查询优化器足够聪明,可以为所有这些构建相同的执行计划:)

他可能会在内部更改查询以首先选择最小的表并与该表进行内部连接。

关于使用内部连接或嵌套连接(最后一个),我更喜欢第一个。将内部连接与表之间的连接进行连接更具可读性,然后,如果需要,还有一个带有限制的 where 子句(在您的示例中,您没有这些限制)。

于 2012-04-26T13:49:55.677 回答