Historia pytania:
Operatory EXISTS i IN są wykorzystywane do filtrowania rekordów na podstawie podzapytania. Od czasów powstania SQL programiści stawali przed dylematem między nimi, starając się zrozumieć, która metoda działa szybciej i w jakich sytuacjach ich zastosowanie jest bardziej wskazane.
Problem:
Głównym zadaniem jest uzyskanie tylko tych wierszy, które mają odpowiedniki w zewnętrznej lub wewnętrznej tabeli, co zawsze ma kluczowe znaczenie dla wydajności przy dużych zestawach danych. Wybór między EXISTS a IN zależy od struktury podzapytania, ilości i unikalności zwracanych wartości, a także od używanego systemu baz danych.
Rozwiązanie:
IN zwykle jest bardziej efektywne, gdy podzapytanie zwraca małą liczbę unikalnych wartości.EXISTS jest preferowane, gdy istotny jest tylko sam fakt istnienia odpowiednich wierszy; nadaje się do dużych podzapytań zwracających tysiące i miliony wierszy.NULL oraz różnicach w optymalizacji w różnych systemach zarządzania bazami danych.Przykład kodu:
-- Użycie IN SELECT name FROM students WHERE id IN (SELECT student_id FROM enrollments WHERE course = 'SQL'); -- Użycie EXISTS SELECT name FROM students WHERE EXISTS (SELECT 1 FROM enrollments WHERE enrollments.student_id = students.id AND enrollments.course = 'SQL');
Kluczowe cechy:
Co się stanie, jeśli w podzapytaniu IN pojawi się NULL?
Wielu uważa, że IN po prostu zignoruje NULL, ale w obecności NULL wynik może stać się nieprzewidywalny. Na przykład zapytanie:
SELECT id FROM orders WHERE client_id IN (1, NULL, 2);
technicznie nie uwzględni wierszy, w których client_id nie jest równy 1 lub 2, ale jeśli w liście podzapytania znajdzie się tylko NULL, wynik będzie pusty.
Czy EXISTS i IN to w pełni wymienne konstrukcje?
Nie. Użycie EXISTS jest często szybsze, ponieważ nie trzeba analizować całego podzapytania. Ponadto, IN nie działa z podzapytaniami zwracającymi wiele kolumn, a EXISTS tak, ponieważ porównanie odbywa się na podstawie warunku w WHERE. Na przykład:
SELECT col1 FROM t1 WHERE (col1, col2) IN (SELECT col3, col4 FROM t2);
Ta wersja jest często nieobsługiwana, natomiast odpowiedni EXISTS — tak.
Czy IN może działać szybciej niż EXISTS przy pracy z indeksowanymi polami?
Tak, jeśli podzapytanie jest małe i na porównywanym polu znajduje się indeks, IN może okazać się szybsze. Jednak w przypadku dużych zbiorów danych lub braku indeksu — przeciwnie.
Analityk stworzył raport metodą IN, nie biorąc pod uwagę, że podzapytanie zwraca setki tysięcy wierszy z NULL. Raport zaczął działać przez kilka minut, czasami tracąc dane.
Plusy:
To samo zapytanie przepisano na EXISTS z dodatkowym warunkiem, przeliczone zostały indeksy.
Plusy: