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?
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 SQL 2008 (Ujistěte se, že 'Zobrazit plán provedení' pro oba výsledky)