Mam przypadek, w którym użycie JOIN lub IN da mi prawidłowe wyniki ... Który z nich ma zwykle lepszą wydajność i dlaczego? Ile to zależy od używanego serwera bazy danych? (FYI używam MSSQL)
Mam przypadek, w którym użycie JOIN lub IN da mi prawidłowe wyniki ... Który z nich ma zwykle lepszą wydajność i dlaczego? Ile to zależy od używanego serwera bazy danych? (FYI używam MSSQL)
Odpowiedzi:
Ogólnie rzecz biorąc, IN
i JOIN
są różne pytania, które mogą dawać różne wyniki.
SELECT a.*
FROM a
JOIN b
ON a.col = b.col
to nie to samo co
SELECT a.*
FROM a
WHERE col IN
(
SELECT col
FROM b
)
chyba że b.col
jest wyjątkowy.
Jest to jednak synonim pierwszego zapytania:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT col
FROM b
)
ON b.col = a.col
Jeśli kolumna łącząca jest UNIQUE
i jest oznaczona jako taka, oba te zapytania dają ten sam plan w programie SQL Server
.
Jeśli nie, to IN
jest szybszy niż JOIN
włączony DISTINCT
.
Zobacz ten artykuł na moim blogu, aby uzyskać szczegółowe informacje na temat wydajności:
IN
implikuje DISTINCT
. SQL Server
jest wystarczająco inteligentny, aby to zauważyć i wygeneruje te same plany dla obu zapytań. Nie jestem jednak pewien, jak RDBMS
zachowają się inni .
Zabawne, że o tym wspomniałeś, napisałem wpis na blogu właśnie na ten temat.
Zobacz Oracle vs MySQL vs SQL Server: Aggregation vs Joins
Krótka odpowiedź: trzeba to przetestować, a poszczególne bazy danych bardzo się różnią.
Trudno to powiedzieć - aby naprawdę dowiedzieć się, który z nich działa lepiej, musiałbyś właściwie sprofilować czasy wykonania.
Ogólnie rzecz biorąc, myślę, że jeśli masz indeksy w kolumnach klucza obcego i używasz tylko (lub głównie) warunków INNER JOIN, to JOIN będzie nieco szybsze.
Ale gdy tylko zaczniesz używać OUTER JOIN lub jeśli nie masz indeksów kluczy obcych, IN może być szybsze.
Marc
Ciekawe podsumowanie logicznych różnic: SQL Server: JOIN vs IN vs EXISTS - logiczna różnica
Jestem prawie pewien, że zakładając, że relacje i indeksy są zachowane, funkcja Join będzie ogólnie działać lepiej (praca z tą operacją wymaga więcej wysiłku niż innych). Jeśli myślisz o tym koncepcyjnie, to jest to różnica między 2 zapytaniami a 1 zapytaniem.
Musisz podłączyć go do Query Analyzer i wypróbować, a zobaczysz różnicę. Spójrz także na Plan wykonania zapytań i spróbuj zminimalizować kroki.
Ten wątek jest dość stary, ale wciąż często się o nim wspomina. Jak na mój gust, jest to trochę niekompletne, ponieważ istnieje inny sposób zapytania bazy danych za pomocą słowa kluczowego EXISTS, który, jak stwierdziłem, jest szybszy niż nie.
Więc jeśli interesują Cię tylko wartości z tabeli a, możesz użyć tego zapytania:
SELECT a.*
FROM a
WHERE EXISTS (
SELECT *
FROM b
WHERE b.col = a.col
)
Różnica może być ogromna, jeśli kolumna nie jest indeksowana, ponieważ db nie musi znajdować wszystkich rekordów w kolumnie b, które mają tę samą wartość w kolumnie, musi tylko znaleźć pierwszy. Jeśli nie ma indeksu na b.col i wiele rekordów w tabeli ba skanowania może być konsekwencją. Z IN lub JOIN byłoby to pełne skanowanie tabeli, z EXISTS byłoby to tylko częściowe skanowanie tabeli (do czasu znalezienia pierwszego pasującego rekordu).
Jeśli jest wiele rekordów w b, które mają tę samą wartość col, zmarnujesz również dużo pamięci na wczytanie wszystkich tych rekordów do tymczasowej przestrzeni tylko po to, aby stwierdzić, że twój warunek jest spełniony. W przypadku istnienia można tego zwykle uniknąć.
Często stwierdzałem, że ISTNIEJE szybciej niż W, nawet jeśli istnieje indeks. Zależy to od systemu bazy danych (optymalizatora), danych i wreszcie od rodzaju używanego indeksu.
Implementacja każdej bazy danych, ale prawdopodobnie możesz się domyślić, że wszystkie one rozwiązują typowe problemy w mniej więcej ten sam sposób. Jeśli używasz MSSQL, spójrz na wygenerowany plan wykonania. Możesz to zrobić, włączając profiler i plany wykonania. To da ci wersję tekstową po uruchomieniu polecenia.
Nie jestem pewien, jakiej wersji MSSQL używasz, ale możesz uzyskać graficzną wersję w SQL Server 2000 w analizatorze zapytań. Jestem pewien, że ta funkcjonalność czai się gdzieś w SQL Server Studio Manager w późniejszych wersjach.
Zapoznaj się z planem egzekucji. O ile to możliwe, unikaj skanowania tabeli, chyba że oczywiście twoja tabela jest mała. W takim przypadku skanowanie tabeli jest szybsze niż użycie indeksu. Zapoznaj się z różnymi operacjami łączenia, które produkuje każdy inny scenariusz.
Optymalizator powinien być wystarczająco inteligentny, aby w obu przypadkach dawać ten sam wynik dla zwykłych zapytań. Sprawdź plan wykonania i powinni dać ci to samo. Jeśli tego nie zrobią, normalnie uznałbym JOIN za szybsze. Jednak wszystkie systemy są różne, więc dla pewności należy profilować kod w systemie.