it-swarm.com.de

SQL JOIN vs IN Leistung?

Ich habe einen Fall, in dem die Verwendung eines JOIN oder eines IN zu den richtigen Ergebnissen führt ... Was hat normalerweise eine bessere Leistung und warum? Inwieweit hängt es davon ab, welchen Datenbankserver Sie verwenden? (FYI ich benutze MSSQL)

150
Polaris878

Im Allgemeinen sind IN und JOIN unterschiedliche Abfragen, die unterschiedliche Ergebnisse liefern können.

SELECT  a.*
FROM    a
JOIN    b
ON      a.col = b.col

ist nicht dasselbe wie

SELECT  a.*
FROM    a
WHERE   col IN
        (
        SELECT  col
        FROM    b
        )

, es sei denn b.col ist einzigartig.

Dies ist jedoch das Synonym für die erste Abfrage:

SELECT  a.*
FROM    a
JOIN    (
        SELECT  DISTINCT col
        FROM    b
        )
ON      b.col = a.col

Wenn die Verbindungsspalte UNIQUE ist und als solche markiert ist, ergeben beide Abfragen denselben Plan in SQL Server.

Ist dies nicht der Fall, ist IN schneller als JOIN auf DISTINCT.

In diesem Artikel in meinem Blog finden Sie Details zur Leistung:

181
Quassnoi

Lustig, dass Sie das erwähnen, ich habe einen Blog-Beitrag zu diesem Thema gemacht.

Siehe Oracle vs MySQL vs SQL Server: Aggregation vs Joins

Kurze Antwort: Sie müssen es testen und die einzelnen Datenbanken variieren stark.

26
cletus

Das ist ziemlich schwer zu sagen - um wirklich herauszufinden, welches besser funktioniert, müssten Sie die Ausführungszeiten tatsächlich profilieren.

Als allgemeine Faustregel denke ich, wenn Sie Indizes für Ihre Fremdschlüsselspalten haben und wenn Sie nur (oder meistens) INNER JOIN-Bedingungen verwenden, ist JOIN etwas schneller.

Sobald Sie jedoch mit der Verwendung von OUTER JOIN beginnen oder wenn Sie keine Fremdschlüsselindizes haben, ist die Eingabe möglicherweise schneller.

Marc

4
marc_s

Eine interessante Beschreibung der logischen Unterschiede: SQL Server: JOIN vs IN vs EXISTS - der logische Unterschied

Ich bin mir ziemlich sicher, dass eine Join-Operation unter der Annahme, dass die Relationen und Indizes beibehalten werden, insgesamt eine bessere Leistung erbringt (die Arbeit mit dieser Operation ist aufwendiger als mit anderen). Wenn Sie konzeptionell darüber nachdenken, dann ist es der Unterschied zwischen 2 Abfragen und 1 Abfrage.

Sie müssen es an den Query Analyzer anschließen und es ausprobieren, um den Unterschied zu erkennen. Schauen Sie sich auch den Query Execution Plan an und versuchen Sie, die Anzahl der Schritte zu minimieren.

4
AdamSane

Dieser Thread ist ziemlich alt, wird aber noch oft erwähnt. Für meinen persönlichen Geschmack ist es ein bisschen unvollständig, weil es eine andere Möglichkeit gibt, die Datenbank mit dem EXISTS-Schlüsselwort zu befragen, das ich als schneller empfunden habe als nicht.

Wenn Sie also nur an Werten aus Tabelle a interessiert sind, können Sie diese Abfrage verwenden:

SELECT  a.*
FROM    a
WHERE   EXISTS (
    SELECT  *
    FROM    b
    WHERE   b.col = a.col
    )

Der Unterschied kann sehr groß sein, wenn col nicht indiziert ist, da die Datenbank nicht alle Datensätze in b finden muss, die denselben Wert in col haben, sondern nur den allerersten. Wenn es keinen Index für b.col und viele Datensätze in b gibt, kann ein Tabellenscan die Folge sein. Mit IN oder JOIN wäre dies ein vollständiger Tabellenscan, mit EXISTS wäre dies nur ein partieller Tabellenscan (bis der erste übereinstimmende Datensatz gefunden wird).

Wenn es in b viele Datensätze gibt, die den gleichen col-Wert haben, verschwenden Sie auch viel Speicher, um alle diese Datensätze in einen temporären Bereich zu lesen, um festzustellen, ob Ihre Bedingung erfüllt ist. Mit existiert kann dies in der Regel vermieden werden.

Ich habe EXISTS oft schneller als IN gefunden, auch wenn es einen Index gibt. Dies hängt vom Datenbanksystem (dem Optimierer), den Daten und nicht zuletzt von der Art des verwendeten Index ab.

3
S.Roeper

Die Implementierung jeder Datenbank, aber Sie können wahrscheinlich davon ausgehen, dass sie alle gängigen Probleme mehr oder weniger auf die gleiche Weise lösen. Wenn Sie MSSQL verwenden, sehen Sie sich den generierten Ausführungsplan an. Sie können dies tun, indem Sie den Profiler und die Ausführungspläne aktivieren. Dadurch erhalten Sie eine Textversion, wenn Sie den Befehl ausführen.

Ich bin nicht sicher, welche Version von MSSQL Sie verwenden, aber Sie können eine grafische Version in SQL Server 2000 im Query Analyzer abrufen. Ich bin mir sicher, dass diese Funktionalität in späteren Versionen in SQL Server Studio Manager nicht überall zu finden ist.

Schauen Sie sich den Ausflugplan an. Vermeiden Sie nach Möglichkeit Tabellenscans, es sei denn, Ihre Tabelle ist klein. In diesem Fall ist ein Tabellenscan schneller als die Verwendung eines Index. Informieren Sie sich über die verschiedenen Verknüpfungsvorgänge, die in den einzelnen Szenarien ausgeführt werden.

3
uriDium

Das Optimierungsprogramm sollte intelligent genug sein, um bei normalen Abfragen dasselbe Ergebnis zu erzielen. Überprüfen Sie den Ausführungsplan und sie sollten Ihnen das gleiche geben. Wenn nicht, würde ich normalerweise den JOIN als schneller betrachten. Alle Systeme sind jedoch unterschiedlich, daher sollten Sie den Code auf Ihrem System profilieren, um sicherzugehen.

1
Joel Coehoorn