2009-05-26 19 views

risposta

16

Aggiornamento

Ho eseguito quattro modi diversi di fare questo attraverso SQL Server 2005 e incluso il piano di esecuzione.

-- 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 

Quindi l'ultimo, sebbene discutibilmente il meno leggibile dei quattro, offre il meglio.

Questa è una sorpresa per me, e onestamente preferisco ancora la sintassi WHERE NOT EXISTS perché penso che sia più esplicita - si legge esattamente come quello che stai cercando di fare.

+0

wow questo è grande. grazie come hai ottenuto le statistiche della CPU? –

+0

Profiler di SQL Server. Ti dice quante letture e tempo di CPU ogni query ha preso (Li ho eseguito uno per uno). –

6

Il mio metodo preferito è una sinistra anti-semi uniscono:

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

Trovo più intitive, flessibile e performante.

Ho scritto un intero articolo su varie strategie di query per cercare l'assenza di dati - dare un'occhiata a here se sei interessato.

+0

Non so se lo trovo più intuitivo di DOVE NON ESISTE, ma +1 comunque. –

+0

+1, outer join e il controllo di 'IS NULL' è sicuramente un approccio performante in mysql (non sono sicuro in che modo confronta le prestazioni con' WHERE NOT EXITS' in varie edizioni di SQL Server, comunque). –

2

Penso che la soluzione più semplice è:

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

Quando è consentita la colonna "ID gruppo" in "Persone", è necessario modificare la query in questo: SELEZIONA * DA GRUPPI WHERE GroupId NON IN (SELECT DISTINCT GroupId FROM People WHERE GroupId NON È NULL) – breez

Problemi correlati