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,disUNIQUEenbis relatief klein vergeleken meta, dan wordt de voorwaarde gepropageerd in de subquery en de gewoneINNER JOINwordt gebruikt (metbleidend) -
Als er een index is op
b.dendis nietUNIQUE, dan wordt de voorwaarde ook gepropageerd enLEFT SEMI JOINis gebruikt. Het kan ook worden gebruikt voor de bovenstaande aandoening. -
Als er een index is op beide
b.dena.cen ze zijn groot, danMERGE SEMI JOINwordt gebruikt -
Als er geen index op een tabel staat, wordt er een hashtabel gebouwd op
benHASH SEMI JOINwordt 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.