从根本上理解3个或更多表sql连接

时间:2011-08-15 13:51:17

标签: sql join inner-join

我提前为这个长期问题道歉。大多数在线文章都没有对此进行讨论,它们只是显示了一个快速的结果集。对于这样一个重要且常用的想法,我想完全理解这一点。我在这里看到了很多关于具体例子的帖子,但没有一个在脑子里有核心想法。我的问题是当你进行3+表连接时,它在内存中是如何工作的?我目前使用的声明是:

select a.cust_id, a.[first name],a.[last name],a.[primary zip],c.jerseynum
from contact as a
join notes as b
on a.cust_id = b.cust_id
join jerseytable as c
on a.cust_id = c.cust_id 

所以在a和b之间的第一次连接之后我们得到一个结果集,我们称之为1 然后我在a和c上加入...这对我来说是模糊的。这个结果集不仅取代了我之前的连接,它是否只将记录添加到1只适合a和c之间的连接?

4 个答案:

答案 0 :(得分:3)

您基本上是在询问数据库如何执行查询。这个领域有很多理论和实践,不止一个答案可以给你。

查询引擎有很多工具可供使用,具体取决于连接,索引和它保留的其他统计信息。它可以构造内存表,重新排序连接(在某些情况下)以更好地限制返回的行数。它可以识别不同连接的结果并将它们合并在一起。

阅读查询计划以开始使用:http://en.wikipedia.org/wiki/Query_plan以及有关查询优化的相关部分。

答案 1 :(得分:3)

JOIN是一个关系运算符:它将两个关系作为参数,结果是另一个关系。

关系运算符可以串在一起。考虑用关系语言教程D:

编写的查询

假设xy是适当声明的关系变量(relvars):

x := a MATCHING b; 
y := x JOIN c {jerseynum};

可替换地:

y := a JOIN c {jerseynum};
x := y MATCHING b; 

但是,上面强制优化器的执行顺序:将中间结果分配给relvars实质上是告诉优化器如何完成它的工作(即不好)。它们可以串在一起,例如如下:

a MATCHING b JOIN c {jerseynum};

SQL FROM子句以类似的方式工作,即不需要分配给中间(派生)表。优化器可以按照它认为合适的任何顺序自由评估它们。相信优化器:)

答案 2 :(得分:1)

a与b连接,然后结果集与c连接。 (如果使用MS SQL Server,则可以在查询执行计划中看到此过程。)

答案 3 :(得分:1)

解析完查询后,数据库引擎将生成计划,其中描述了获取查询结果所需采取的实际步骤。您应该检查您的实际计划,以了解实际情况。 基本上,无论你在sql中编写的顺序如何,优化器都会选择连接的顺序。连接的实际顺序将取决于索引和数据上保留的统计信息。 请参阅有关查询优化器http://research.microsoft.com/pubs/76059/pods98-tutorial.pdf

的这篇文章