Was ist der Unterschied zwischen diesen T-SQL-Abfragen mit OR?

8

Ich verwende Microsoft SQL Server 2008 (SP1, x64). Ich habe zwei Abfragen, die dasselbe tun, oder so denke ich, aber sie haben völlig andere Abfragepläne und Leistung.

Abfrage 1:

%Vor%

Abfrage 2:

%Vor%

Abfrage 1 ist schnell, wie ich es erwarten würde, während Abfrage 2 sehr langsam ist. Die Abfragepläne sehen ganz anders aus.

Ich möchte, dass Abfrage 2 so schnell ist wie Abfrage 1. Ich habe Software, die Abfrage 2 verwendet, und ich kann das nicht in Abfrage 1 ändern. Ich kann die Datenbank ändern.

Einige Fragen:

  • Warum sind die Abfragepläne anders?
  • kann ich SQL Server irgendwie "unterrichten", dass Abfrage 2 gleich Abfrage 1 ist?

Alle Tabellen haben (gruppierte) Primärschlüssel und richtige Indizes für alle Spalten:

%Vor%

Die Tabellen werden nach dem anfänglichen Füllen nicht geändert. Ich bin der Einzige, der sie befragt. Sie enthalten Millionen von Datensätzen (Tabelle_a: 5M, Tabelle_B: 4M, Tabelle_C: 12M), aber die Verwendung von nur 1% ergibt ähnliche Ergebnisse.

Bearbeiten: Ich habe versucht, FOREIGN KEYs für c_a_id und c_b_id hinzuzufügen, aber das hat die Abfrage 1 nur langsamer gemacht ...

Ich hoffe, jemand kann sich die Abfragepläne ansehen und den Unterschied erklären.

>     
Michel de Ruiter 13.03.2012, 11:45
quelle

3 Antworten

1

Join sind langsamer, lassen Sie mich by design sagen. Die erste Abfrage verwendet eine Unterabfrage (cachefähig), um Datensätze zu filtern, so dass weniger Daten (und weniger Zugriffe auf jede Tabelle) erzeugt werden.

Hast du diese gelesen:

Was ich meine, ist, dass mit IN die DB bessere Optimierungen machen kann wie das Entfernen von Duplikaten, das Stoppen beim ersten Spiel und ähnliches (und das sind von Schule Erinnerungen also Ich bin mir sicher, dass es viel besser geht). Also ich rate die Frage ist nicht, warum QP anders ist, aber wie schlau wie tief Optimierungen gehen können.

    
Adriano Repetti 13.03.2012 11:53
quelle
0

Sie vergleichen nicht-äquivalente Abfragen, auch wenn Sie linkes Join auf ganz ungewöhnliche Weise verwenden. Wenn Sie alle Einträge in table_c auswählen möchten, die Datensätze entweder in table_a oder table_b verknüpft haben, sollten Sie im Allgemeinen eine exists-Anweisung verwenden:

%Vor%     
Vitaliy Kalinin 13.03.2012 11:58
quelle
0

Da Sie die Abfrage nicht ändern können, können Sie zumindest die Umgebung der Abfrage verbessern.

  1. Markieren Sie Ihre Abfrage, klicken Sie mit der rechten Maustaste darauf in SSMS und wählen Sie "Analysieren" Abfrage im Datenbankoptimierungsratgeber. "
  2. Führen Sie die Analyse aus, um herauszufinden, ob Sie zusätzliche Indizes oder benötigen Statistiken gebaut.
  3. Beachten Sie die Hinweise von SQL Server.
JeffO 13.03.2012 12:58
quelle