sql >> Databáze >  >> RDS >> Sqlserver

Výkon INNER JOIN vs. LEFT JOIN v SQL Server

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 .



  1. Co je to Multi Dimension OLAP CUBE a uveďte příklad krychle s více než 3 rozměry

  2. Jak mohu zadat heslo pro 'psql' neinteraktivně?

  3. Webrick reaguje velmi pomalu. Jak to urychlit?

  4. Jak se mohu zbavit těchto komentářů ve výpisu MySQL?