2009-05-26 17 views

Odpowiedz

16

Aktualizacja

Zabrakło mi cztery różne sposoby, aby to zrobić za pomocą programu SQL Server 2005 i obejmował plan wykonania.

-- 269 reads, 16 CPU 
SELECT * 
FROM Groups 
WHERE NOT EXISTS (
    SELECT * 
    FROM People 
    WHERE People.GroupId = Groups.GroupId 
); 

-- 249 reads, 15 CPU 
SELECT * 
FROM Groups 
WHERE (
    SELECT COUNT(*) 
    FROM People 
    WHERE People.GroupId = Groups.GroupId 
) = 0 

-- 249 reads, 14 CPU 
SELECT * 
FROM Groups 
WHERE GroupId NOT IN (
    SELECT DISTINCT GroupId 
    FROM Users 
) 

-- 10 reads, 12 CPU 
SELECT * 
FROM Groups 
    LEFT JOIN Users ON Users.GroupId = Groups.GroupId 
WHERE Users.GroupId IS NULL 

Tak więc ostatni, choć prawdopodobnie najmniej czytelny z czterech, wykonuje najlepiej.

To zaskakuje mnie i szczerze mówiąc nadal wolę składnię WHERE NOT EXISTS, ponieważ uważam, że jest bardziej jednoznaczna - czyta dokładnie tak, jak próbujesz.

+0

wow to jest super. dziękuję w jaki sposób otrzymałeś statystyki procesora? –

+0

Profiler programu SQL Server. Informuje, ile odczytów i czasu procesora zajęło każde zapytanie (sprawdziłem je jeden po drugim). –

6

Moja metoda jest preferowana w lewo anty-semi dołączyć:

SELECT g.* 
FROM  Groups g 
LEFT JOIN People p ON g.GroupID = p.GroupID 
WHERE  p.GroupID IS NULL 

Uważam to najbardziej intitive, elastyczne i wydajnych.

Napisałem cały artykuł o różnych strategiach wyszukiwania w celu wyszukania braku danych - spójrz na here, jeśli jesteś zainteresowany.

+0

Nie wiem, czy uważam, że jest to bardziej intuicyjne, niż GDZIE NIE ZNAJDUJE, ale +1. –

+0

+1, sprzężenie zewnętrzne i sprawdzenie "IS NULL" to z pewnością dobrze działające podejście w mysql (nie mam pewności, jak porównuje wydajność z "WHERE NOT EXITS" w różnych wersjach SQL Server). –

2

Myślę, że najprostszym rozwiązaniem jest:

SELECT * 
FROM GROUPS 
WHERE GroupId NOT IN (SELECT DISTINCT GroupId FROM People) 
+0

Gdy wartości Null są dozwolone dla kolumny "GroupId" w "Osoby", należy zmienić zapytanie na: SELECT * Z GRUP WHERE GroupId NOT IN (WYBIERZ DISTINCT GroupId FROM People WHERE GroupId NIE JEST NULL) – breez

Powiązane problemy