Bijwerken:
Dit artikel in mijn blog vat zowel mijn antwoord als mijn opmerkingen bij andere antwoorden samen en toont de daadwerkelijke uitvoeringsplannen:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Deze vragen zijn niet gelijkwaardig. Ze kunnen verschillende resultaten opleveren als uw tabel b
is niet sleutel bewaard (d.w.z. de waarden van b.d
zijn niet uniek).
Het equivalent van de eerste vraag is het volgende:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Als b.d
is UNIQUE
en als zodanig gemarkeerd (met een UNIQUE INDEX
of UNIQUE CONSTRAINT
), dan zijn deze zoekopdrachten identiek en zullen ze hoogstwaarschijnlijk identieke abonnementen gebruiken, aangezien SQL Server
is slim genoeg om hier rekening mee te houden.
SQL Server
kan een van de volgende methoden gebruiken om deze query uit te voeren:
-
Als er een index is op
a.c
,d
isUNIQUE
enb
is relatief klein vergeleken meta
, dan wordt de voorwaarde gepropageerd in de subquery en de gewoneINNER JOIN
wordt gebruikt (metb
leidend) -
Als er een index is op
b.d
end
is nietUNIQUE
, dan wordt de voorwaarde ook gepropageerd enLEFT SEMI JOIN
is gebruikt. Het kan ook worden gebruikt voor de bovenstaande aandoening. -
Als er een index is op beide
b.d
ena.c
en ze zijn groot, danMERGE SEMI JOIN
wordt gebruikt -
Als er geen index op een tabel staat, wordt er een hashtabel gebouwd op
b
enHASH SEMI JOIN
wordt gebruikt.
Geen van beide van deze methoden evalueert de hele subquery elke keer opnieuw.
Zie dit bericht in mijn blog voor meer informatie over hoe dit werkt:
Er zijn links voor alle RDBMS
's van de grote vier.