哪个更好:加入条件多还是条件多?


13

我正在尝试比较两个查询:

查询1:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a
WHERE tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  AND tableA.e=tableB.e 

查询2:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a AND tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  
WHERE tableA.e=tableB.e 

我是否可以正确地说这两个查询给出相同的结果?

进一步说第一个查询建立一个更大的表并对其做更大的WHERE条件是否正确;而第二种情况是我们有一个较小的构造表,WHERE然后将其应用于简单表。

假设结果相同,则应首选哪个查询?是否存在明显的性能问题?


3
不,你说的不对。可能是INNER JOIN,但使用LEFT JOIN会返回不同的结果。基本上,您在WHERE第二个查询中添加的条件正在将您的条件转换JOININNER JOIN
Lamak

喔好吧。我按照你说的去做。如果我进行编辑以解决INNER JOIN我对性能的问题仍然有效?
杰夫

4
对于INNER JOIN,性能应该没有差异。也就是说,为了便于阅读和正确表达意图,您应该在中使用联接条件,ON并在中使用过滤条件WHERE
亚伦·伯特兰

@ypercube对,我错过了这种情况。
Lamak

Answers:


10

如果我们认为您使用INNER JOIN而不是LEFT JOIN(似乎是您的意图),那么这两个查询在功能上是等效的。查询优化器将检查和评估您的WHERE子句中的条件,并FROM在构建查询计划时考虑所有这些因素,以便获得最有效的执行计划。如果我们EXPLAIN对两个语句都执行“ a”,则会得到相同的结果:

查询1

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
WHERE 
  tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
  AND tableA.ColE=tableB.ColE

[结果]

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

查询2

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
  AND tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
WHERE
  tableA.ColE=tableB.ColE

[结果]

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

您可以通过以下链接查看全部详细信息。我还创建了一个SQL 2008示例,以便您可以比较两个引擎的工作方式(相同):

MySQL查询示例

SQL 2008查询示例(确保两个结果都“查看执行计划”)


感谢您的详细解决方案。我尝试INNER JOIN而不是尝试,LEFT JOIN但在十分之一的时间内得到了相同的输出。我想我知道为什么我得到相同的输出,但是为什么INNER JOIN会有更好的性能呢?
Geoff

4
作为LEFT JOIN外部联接,它不能将数据集限制在集合的完全返回侧,并且将尝试从该表(在本例中为TableA)检索所有行。如果使用INNER JOIN,它可以在两个表上利用该条件并限制数据集,从而提供更快的回报。
Mike Fal 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.