2009-02-23 38 views
4

我只是想知道下面的所有连接在逻辑上是否相等,如果不是,为什么不呢?所有这些SQL连接在逻辑上是否相同?

SELECT t1.x, t2.y from t1, t2 where t1.a=t2.a and t1.b=t2.b and t1.c = t2.c; 

SELECT t1.x, t2.y from t1 join t2 on t1.a=t2.a where t1.b=t2.b and t1.c = t2.c; 

SELECT t1.x, t2.y from t1 join t2 on t1.a=t2.a and t1.b=t2.b where t1.c = t2.c; 

SELECT t1.x, t2.y from t1 join t2 on t1.a=t2.a and t1.b=t2.b and t1.c = t2.c; 

我想我真正的问题是:“上”做一些只从具有“开”相与在一起的多条件组合的不同“其中”用?

我使用MySQL,以防万一。

回答

5

它们在逻辑上是等效的,应该产生相同的结果。然而,最后一个是优选的,因为它更准确地说明了查询的语义 - 即“连接表t1和t2”。

WHERE子句应该用于“过滤”连接的结果 - 例如,

... WHERE t2.some_col > 10 

此外,正如康斯坦丁在另一个答案中所说,如果连接是一个外部连接,4个查询将会不同。

+0

第一个查询是否会完全执行交叉连接,还是DBMS足够智能以便首先应用where子句? – 2009-02-23 17:16:36

+0

从SQL Server 2000版开始,将推断顶层示例为INNER JOIN。测试它并查看执行计划 – 2009-02-23 17:18:48

2

是的,正如其他人所说的那样,结果在所有这些查询中都是相同的。

FWIW,你也可以使用这个简写语法当你做对是相同的两个表中列名等值连接:

SELECT t1.x, t2.y from t1 join t2 using (a, b, c); 

至于优化,它应该是优化相同。也就是说,RDBMS应该足够聪明,可以分析WHERE语法相同,并执行连接,而不是生成中间的巨大交叉连接结果并向其应用过滤条件。这是一种常见的查询类型,对于给定的RDBMS实现来说,识别和优化它也很常见。

在MySQL的情况下,连接和哪里(种)一起评估。尝试使用EXPLAIN分析您的查询。如果“type”列指示“eq_ref”,则表示它正在使用索引连接。这是与优化有关的最佳加入类型。如果“type”是“ref”,那也不错。

无论是将条件放在JOIN...ON子句还是WHERE子句中,都可以获得这些连接优化类型。

1

它们在逻辑上是等效的。但是,定义连接条件的位置会影响应用where子句的临时表中使用的记录数量。也就是说,

如果表T1,T2和T3各为10条记录,声明,

SELECT t1.x, t2.y from t1, t2 where t1.a=t2.a and t1.b=t2.b and t1.c = t2.c; 

结果1000条记录的三个表记录的排列,然后应用where子句。

对于

SELECT t1.x, t2.y from t1 join t2 on t1.a=t2.a and t1.b=t2.b and t1.c = t2.c; 

只有十个记录在临时表中的任何地方施加条款(在这种情况下无)之前。使用大型表格时,第二种方法要快得多。