sql >> Database >  >> RDS >> Sqlserver

IN vs. JOIN met grote rijen

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 is UNIQUE en b is relatief klein vergeleken met a , dan wordt de voorwaarde gepropageerd in de subquery en de gewone INNER JOIN wordt gebruikt (met b leidend)

  • Als er een index is op b.d en d is niet UNIQUE , dan wordt de voorwaarde ook gepropageerd en LEFT SEMI JOIN is gebruikt. Het kan ook worden gebruikt voor de bovenstaande aandoening.

  • Als er een index is op beide b.d en a.c en ze zijn groot, dan MERGE SEMI JOIN wordt gebruikt

  • Als er geen index op een tabel staat, wordt er een hashtabel gebouwd op b en HASH 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.



  1. Kan gegevens niet van bestand naar Oracle-tabel laden met executeMany()

  2. Alternatief voor het gebruik van WHERE ... IN (...) voor langzame SQL-query's

  3. Som resultaten van twee select statements

  4. Fout bij casten van T4CConnection naar OracleConnection