哪个更好:许多加入条件或许多 where 条件?

Geo*_*off 14 mysql performance

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

查询 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 
Run Code Online (Sandbox Code Playgroud)

查询 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 
Run Code Online (Sandbox Code Playgroud)

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

此外,说第一个查询构建了一个更大的表来做更大的WHERE条件是否正确?而在第二种情况下,我们有一个较小的构造表,然后将简单WHERE应用于该表。

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

Mik*_*Fal 10

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

查询 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
Run Code Online (Sandbox Code Playgroud)

[结果] :

| 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 |
Run Code Online (Sandbox Code Playgroud)

查询 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
Run Code Online (Sandbox Code Playgroud)

[结果] :

| 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 |
Run Code Online (Sandbox Code Playgroud)

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

MySQL查询示例

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

  • 由于`LEFT JOIN` 是外连接,它不能限制数据集的完整返回侧的数据集,并会尝试从该表(在本例中为表A)检索所有行。如果您使用`INNER JOIN`,它可以在两个表上利用该条件并限制数据集,从而提供更快的回报。 (4认同)