LEFT JOIN není absolutně rychlejší než INNER JOIN . Ve skutečnosti je pomalejší; podle definice vnější spojení (LEFT JOIN nebo RIGHT JOIN ) musí udělat veškerou práci INNER JOIN plus práce navíc s nulovým rozšířením výsledků. Očekávalo by se také, že vrátí více řádků, což dále prodlouží celkovou dobu provádění jednoduše kvůli větší velikosti sady výsledků.
(A to i v případě, že LEFT JOIN byli rychlejší v konkrétním situace kvůli nějakému obtížně představitelnému souběhu faktorů, není funkčně ekvivalentní INNER JOIN , takže nemůžete jednoduše nahradit všechny výskyty jednoho za druhý!)
Vaše problémy s výkonem s největší pravděpodobností leží jinde, například v tom, že nemáte správně indexovaný kandidátský klíč nebo cizí klíč. 9 stolů je poměrně hodně, takže zpomalení může být doslova téměř kdekoli. Pokud zveřejníte své schéma, možná vám budeme moci poskytnout další podrobnosti.
Upravit:
Když se nad tím zamyslím dále, napadá mě jedna okolnost, za které LEFT JOIN může být rychlejší než INNER JOIN , a to je, když:
- Některé tabulky jsou velmi malý (řekněme do 10 řádků);
- Tabulky nemají dostatečné indexy k pokrytí dotazu.
Zvažte tento příklad:
CREATE TABLE #Test1
(
ID int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
)
INSERT #Test1 (ID, Name) VALUES (1, 'One')
INSERT #Test1 (ID, Name) VALUES (2, 'Two')
INSERT #Test1 (ID, Name) VALUES (3, 'Three')
INSERT #Test1 (ID, Name) VALUES (4, 'Four')
INSERT #Test1 (ID, Name) VALUES (5, 'Five')
CREATE TABLE #Test2
(
ID int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
)
INSERT #Test2 (ID, Name) VALUES (1, 'One')
INSERT #Test2 (ID, Name) VALUES (2, 'Two')
INSERT #Test2 (ID, Name) VALUES (3, 'Three')
INSERT #Test2 (ID, Name) VALUES (4, 'Four')
INSERT #Test2 (ID, Name) VALUES (5, 'Five')
SELECT *
FROM #Test1 t1
INNER JOIN #Test2 t2
ON t2.Name = t1.Name
SELECT *
FROM #Test1 t1
LEFT JOIN #Test2 t2
ON t2.Name = t1.Name
DROP TABLE #Test1
DROP TABLE #Test2
Pokud toto spustíte a zobrazíte plán provádění, uvidíte, že INNER JOIN dotaz skutečně stojí více než LEFT JOIN , protože splňuje dvě výše uvedená kritéria. Je to proto, že SQL Server chce provést hašovací shodu pro INNER JOIN , ale dělá vnořené smyčky pro LEFT JOIN; první je normálně mnohem rychleji, ale protože počet řádků je tak malý a neexistuje žádný index k použití, operace hašování se ukazuje jako nejdražší část dotazu.
Stejný efekt můžete vidět, když napíšete program ve svém oblíbeném programovacím jazyce, který provede velké množství vyhledávání v seznamu s 5 prvky, oproti hashovací tabulce s 5 prvky. Kvůli velikosti je verze hashovací tabulky ve skutečnosti pomalejší. Ale zvětšete to na 50 prvků nebo 5000 prvků a verze seznamu se zpomalí na procházení, protože je to O(N) vs. O(1) pro hashtable.
Ale změňte tento dotaz tak, aby byl na ID místo Name a uvidíte úplně jiný příběh. V takovém případě provede vnořené smyčky pro oba dotazy, ale INNER JOIN verze je schopna nahradit jeden z clusterovaných indexových skenů hledáním – což znamená, že to bude doslova řádově rychlejší s velkým počtem řádků.
Takže závěr je víceméně to, co jsem zmínil o několik odstavců výše; téměř jistě se jedná o problém indexování nebo pokrytí indexu, případně v kombinaci s jednou nebo více velmi malými tabulkami. Toto jsou jediné okolnosti, za kterých SQL Server může někdy zvolte horší plán provedení pro INNER JOIN než LEFT JOIN .