it-swarm-eu.dev

Který je lepší: mnoho podmínek pro připojení nebo mnoho podmínek pro podmínky?

Snažím se porovnat dva dotazy:

Dotaz 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 

Dotaz 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 

Mám pravdu, že tyto dva dotazy přinášejí stejné výsledky?

Dále je správné říci, že první dotaz vytváří větší tabulku, pro kterou má být provedena větší podmínka WHERE; zatímco ve druhém případě máme menší sestavenou tabulku, na kterou se potom použije jednoduchý WHERE.

Za předpokladu, že výsledky jsou stejné, který dotaz by měl být upřednostňován? Existuje zjevný problém s výkonem?

14
Geoff

Pokud vezmeme v úvahu, že používáte INNER JOIN namísto LEFT JOIN (což se zdá být vaším záměrem) jsou tyto dva dotazy funkčně ekvivalentní. Optimalizátory dotazů zkontrolují a vyhodnotí kritéria ve vaší klauzuli WHERE a vaší klauzuli FROM a při vytváření plánů dotazů zváží všechny tyto faktory, aby dosáhly nejefektivnějšího plánu provádění. Pokud uděláme EXPLAIN pro oba příkazy, dostaneme stejný výsledek:

Dotaz 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

[Výsledky] :

| 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 |

Dotaz 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

[Výsledky] :

| 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 |

Úplné podrobnosti můžete zkontrolovat pomocí následujících odkazů. Také jsem vytvořil příklad SQL 2008, takže můžete porovnat, jak tyto dva motory fungují (což je stejné):

Příklad dotazu MySQL

Příklad dotazu SQL 2008 (Ujistěte se, že 'Zobrazit plán provedení' pro oba výsledky)

10
Mike Fal