连接查询中的表顺序

时间:2010-10-20 10:43:03

标签: sql oracle join

我在Oracle文档中找到了这一段

  

如果要选择每个的名称   部门及其名称   经理,你可以写入查询   两种方式之一。在第一个例子中   接下来,提示/ ++有序++ /   说按顺序进行加入   表格出现在FROM子句中   尝试优化连接顺序。

SELECT /*+ordered*/ d.NAME, e.NAME
FROM DEPT d, EMP e WHERE d.MGR = e.SS#
     

或:

SELECT /*+ordered*/ d.NAME, e.NAME 
FROM EMP e, DEPT d WHERE d.MGR = e.SS# 
     

假设有10个部门   和1000名员工,那内心   每个查询中的表都有一个索引   连接列。在第一个查询中,   第一桌产生10个资格   行(在本例中为整个表)。   在第二个查询中,第一个表   产生1000个符合条件的行。该   第一个查询将访问EMP表   10次​​,扫描DEPT表一次。   第二个查询将扫描EMP   表一次,但将访问DEPT   表1000次。所以第一个   查询会表现得更好。作为一个   经验法则,表应该是   安排从最小的有效   数字行最大有效   行数。有效行大小   通过获取查询中的表   应用逻辑条件   完全在那张桌子上解决。

但我没有正确理解这一点。如果表t1中的表{1}和m行中有n行,那么在这两种情况下,sql引擎都不会通过m x n行吗?

更新:感谢所有回复。我不会压倒优化器,只想确认我的想法。

3 个答案:

答案 0 :(得分:4)

嗯,在第一种情况下,逻辑读取的数量是10 + 10,在第二种1000 + 1000中,每个部门平均读取100次。

然而,用这样的ORDERED命令编写查询不是正常的做法。最好在大多数情况下将优化留给优化器。

我不确定你从哪个文档中引用了这个文档,但是在我看到它的前面是你省略了这个非常重要的段落。我在这里引用它是为了其他人可能会认为这种编写查询的方法是标准的:

  

通常优化器选择最好   执行计划,最佳秩序   要加入的表格。如果是   优化器并没有产生好处   执行计划,你可以控制   使用HINTS执行的顺序   功能SQL。有关更多信息,请参阅   Oracle Database Lite SQL   参考

- Oracle® Database Lite Developer's Guide

答案 1 :(得分:2)

这取决于WHERE语句。

SELECT /++ordered++/ d.NAME, e.NAME FROM DEPT d, EMP e WHERE d.MGR = e.SS#

将为每个部门选择所有经理。由于有10个部门,因此可以获取10个记录。

SELECT /++ordered++/ d.NAME, e.NAME FROM EMP e, DEPT d

这将选择所有具有其所在部门名称的员工。由于有1000名员工,您的结果集将有1000行。

JOIN永远不会让您的引擎循环m x n行,如果m

,则内部联接的结果集始终为m < n

答案 2 :(得分:1)

你真的在oracle docs中找到了吗?

你不应该使用ORDERED提示,让oracle为你做决定 - 现在大部分时间工作得非常好。

然而,联接顺序在性能上有所不同。

这个例子似乎讨论了NESTED LOOPS加入:

Case 1:
 -> 1 lookup to find 10 rows in table A
 -> 10 index lookups in table B

Case 2:
 -> 1 lookup to find 1000 rows in table B 
 -> 1000 index lookups in table A