7

我想确认 SQL 查询

SELECT ....
  FROM apples,
       oranges
       LEFT JOIN kiwis ON kiwis.orange_id = oranges.id,
       bananas
 WHERE ....

完全等同于 FROM 子句中的其他排列,例如

SELECT ....
  FROM oranges
       LEFT JOIN kiwis ON kiwis.orange_id = oranges.id,
       bananas,
       apples
 WHERE ....

或者

SELECT ....
  FROM bananas,
       apples,
       oranges
       LEFT JOIN kiwis ON kiwis.orange_id = oranges.id
 WHERE ....

只要橙子和猕猴桃之间的显式 LEFT JOIN 保持不变。从我在各种文档中阅读的内容来看,返回的集合应该完全相同。

我真的只关心查询的结果,而不关心它在实际数据库中的性能。(我使用的是 PostgreSQL 8.3,AFAIK 不支持关于连接顺序的优化器提示,并将尝试自动创建最佳查询计划)。

4

3 回答 3

15

它是相同的,但是对于隐式的CROSS JOIN ,它是模棱两可的。使用显式 JOINS。

如果您在 WHERE 子句中加入,则结果可能会有所不同,因为连接和过滤器混淆了。

SELECT ....
  FROM apples a
       JOIN
       bananas b ON ...
       JOIN 
       oranges o ON ...
       LEFT JOIN
       kiwis k ON k.orange_id = o.id
 WHERE (filters only)

笔记:

  • INNER JOINS 和 CROSS JOINS 是可交换的和关联的:顺序通常无关紧要。
  • OUTER JOINS 不是您确定的
  • SQL 是声明性的:你告诉优化器你想要什么,而不是如何去做。这消除了 JOIN 顺序注意事项(以前 2 项为准)
于 2011-02-15T21:28:49.523 回答
1

这种情况在使用显式 JOIN 子句控制规划器中进行了总结。外部连接不会重新排序,内部连接可以。您可以通过在运行查询之前删除 *join_collapse_limit* 来强制执行特定的优化器顺序,并将事物按照您想要的顺序排列。这就是您在该区域的数据库中“提示”的方式。

通常,您希望使用 EXPLAIN 来确认您获得的订单,并且有时可以用来直观地确认两个查询正在获得相同的计划。

于 2011-02-15T23:44:53.120 回答
0

我已经做了很多年的 SQL,根据我的经验,表顺序并不重要。数据库会将查询视为一个整体并创建最佳查询计划。这就是为什么数据库公司在查询计划优化方面雇佣了许多拥有博士学位的人。

如果数据库供应商按照您个人在查询中列出 SQL 的顺序进行优化,那么数据库供应商将在商业上自杀。

于 2011-02-15T21:25:28.357 回答