SQL JOIN vs IN Leistung?


164

Ich habe einen Fall, in dem die Verwendung eines JOIN oder eines IN die richtigen Ergebnisse liefert ... Was hat normalerweise eine bessere Leistung und warum? Wie stark hängt es davon ab, welchen Datenbankserver Sie ausführen? (Zu Ihrer Information, ich benutze MSSQL)


:) Ich habe tatsächlich nach einem anderen Artikel gesucht, den ich verwendet habe, als ich vor
einiger Zeit

Entschuldigung für den möglichen Betrug ... habe diese Frage nicht gefunden, als ich gesucht habe
Polaris878

Antworten:


196

Im Allgemeinen INund JOINgibt verschiedene Abfragen , die zu unterschiedlichen Ergebnissen führen 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 b.colsei denn, es 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 UNIQUEals solche gekennzeichnet ist, ergeben beide Abfragen den gleichen Plan in SQL Server.

Wenn nicht, INist es schneller als JOINein DISTINCT.

Weitere Informationen zur Leistung finden Sie in diesem Artikel in meinem Blog:


Ja, es macht Sinn, dass sie dasselbe ausführen würden, wenn die Verbindungsspalte eindeutig ist (was in meinem Fall der Fall ist)
Polaris878

1
Sollte ich in ähnlicher Weise IN (SELECT DISTINCT ...) oder einfach IN (SELECT ...) verwenden?
Moo

8
@ orlandu63: INimpliziert DISTINCT. SQL Serverist klug genug, um es zu bemerken, und generiert für beide Abfragen dieselben Pläne. Ich bin mir jedoch nicht sicher, wie sich andere RDBMSverhalten werden.
Quassnoi

>> IN und JOIN sind unterschiedliche Abfragen, die zu unterschiedlichen Ergebnissen führen können. Können Sie bitte erklären, warum in diesem Fall ein anderes Ergebnis erzielt wird, auch wenn b.col nicht eindeutig ist?
Abhijeet



6

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 der JOIN etwas schneller.

Sobald Sie jedoch OUTER JOIN verwenden oder Fremdschlüsselindizes fehlen, ist IN möglicherweise schneller.

Marc


Ich habe das auch gedacht ... weil es so aussieht, als
ob

4

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

Ich bin mir ziemlich sicher, dass unter der Annahme, dass die Relationen und Indizes beibehalten werden, ein Join insgesamt eine bessere Leistung erbringt (es wird mehr Aufwand betrieben, mit dieser Operation zu arbeiten als mit anderen). Wenn Sie konzeptionell darüber nachdenken, 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. Sehen Sie sich auch den Abfrageausführungsplan an und versuchen Sie, die Schritte zu minimieren.


4

Dieser Thread ist ziemlich alt, wird aber immer noch oft erwähnt. Für meinen persönlichen Geschmack ist es etwas unvollständig, da es eine andere Möglichkeit gibt, die Datenbank mit dem Schlüsselwort EXISTS abzufragen, das ich häufig als schneller empfand.

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 den gleichen Wert in col haben, sondern nur den allerersten. Wenn es keinen Index für b.col gibt und viele Datensätze im Ba-Tabellenscan die Folge sein könnten. Mit IN oder einem JOIN wäre dies ein vollständiger Tabellenscan, mit EXISTS wäre dies nur ein teilweiser Tabellenscan (bis der erste übereinstimmende Datensatz gefunden wird).

Wenn es in b viele Datensätze gibt, die denselben Spaltenwert 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 vorhanden kann dies in der Regel vermieden werden.

Ich habe EXISTS oft schneller als IN gefunden, selbst 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
Auf MSSql scheint die Tatsache, dass es besser ist als ein IN, nicht wahr zu sein. Für weitere Informationen: explainextended.com/2009/06/16/in-vs-join-vs-exists Hier können Sie lesen: "Viele denken, dass EXISTS effizienter ist als IN, weil EXISTS nur eine Zeile zurückgibt. Dies ist Dies gilt nicht für SQL Server. Wie aus den obigen Beispielen hervorgeht, erstellen EXISTS und IN genau dieselben Pläne. Dies liegt daran, dass EXISTS flexibler als IN ist. Ein IN kann immer als EXISTS umgeschrieben werden (unter Verwendung einer einfachen WHERE-Bedingung mit einem Equijoin) ) aber nicht umgekehrt. "
Micaël Félix

3

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 Abfrageanalysator abrufen. Ich bin sicher, dass diese Funktionalität in späteren Versionen in SQL Server Studio Manager lauert.

Schauen Sie sich den Ausführungsplan an. Vermeiden Sie Tabellenscans so weit wie möglich, es sei denn, Ihre Tabelle ist natürlich klein. In diesem Fall ist ein Tabellenscan schneller als die Verwendung eines Index. Informieren Sie sich über die verschiedenen Verknüpfungsvorgänge, die jedes Szenario erzeugt.


1

Das Optimierungsprogramm sollte intelligent genug sein, um bei normalen Abfragen in beiden Fällen das gleiche 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.


5
Sollte tun? Vielleicht. Macht es? Siehe meinen Beitrag.
Cletus
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.