database-tuning

___ qstnhdr ___ Vermeiden Sie den Sortieroperator im Indexplan ___ answer43498025 ___

Die zweite Abfrage von Ihnen enthält die UserId-Bedingung nicht und daher ist es keine äquivalente Abfrage. Der Grund, warum die erste Abfrage nicht von Ihren Indizes in LogTable abgedeckt wird, ist die Tatsache, dass UserId nicht in ihnen vorhanden ist (und Sie müssen auch den Join ausführen). Daher muss SQL Server den Tabellen beitreten (Hash Join, Merge Join oder Nested-Loop Join). SQL Server wählt den Hash-Join korrekt aus, da die Zwischenergebnisse groß sind und nicht gemäß der LogID sortiert sind. Wenn Sie ihnen das Zwischenergebnis sortiert nach der LogID (Ihre zweite Bearbeitung) geben, dann verwendet er Merge Join, aber sortieren nach dem DateSend ist stil erforderlich. Die einzige Lösung ohne Sortierung ist das Erstellen einer indizierten materialisierten Ansicht:

%Vor%

Die Ansicht muss mit noexpand-Hinweis verwendet werden, damit der Optimierer den CIX_vCustomerOrders-Index finden kann:

%Vor%

Diese Abfrage ist eine äquivalente Abfrage für Ihre erste Abfrage. Sie können die Richtigkeit überprüfen, wenn Sie die folgende Zeile einfügen:

%Vor%

dann gibt meine Abfrage immer noch das korrekte Ergebnis (10000 Zeilen) zurück, Ihre zweite Abfrage gibt jedoch 10001 Zeilen zurück. Sie können versuchen, einige andere Zeilen zu löschen oder einzufügen, und die Ansicht ist immer noch auf dem neuesten Stand und Sie erhalten korrekte Ergebnisse von meiner Abfrage.

    
___ tag123sql ___ Structured Query Language (SQL) ist eine Sprache für die Abfrage von Datenbanken. Fragen sollten Codebeispiele, Tabellenstruktur, Beispieldaten und ein Tag für die verwendete DBMS-Implementierung (z. B. MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 usw.) enthalten. Wenn sich Ihre Frage nur auf ein bestimmtes DBMS bezieht (verwendet bestimmte Erweiterungen / Funktionen), verwenden Sie stattdessen das Tag des DBMS. Antworten auf mit SQL gekennzeichnete Fragen sollten den ISO / IEC-Standard SQL verwenden. ___ answer43491667 ___

Ich denke, der Grund könnte hier sein:

%Vor%

Ihre Tabelle enthält keinen Index für LogID. Diese Spalte wird jedoch für %code% verwendet. %code% bedeutet nicht, dass dieser Index nach %code% durchsucht werden kann. Dies ist nur ein kleines bisschen schneller, wenn Sie nach %code% suchen und Sie die entsprechende %code% brauchen (Sie müssen das nicht nachsehen)

Wenn Sie sich über LogID anmelden, sollte es am schnellsten sein, die Liste vorher zu sortieren, da kein Index verfügbar ist ...

Wenn Platz keine Rolle spielt (und Performance einfügen / aktualisieren, können Sie einen Index umgekehrt hinzufügen, aber ich würde vorschlagen, einen zweispaltigen Clusterschlüssel mit zu verwenden LogId an der ersten Position und - falls erforderlich - ein einfacher nicht gruppierter Index für UserId.

    
___ tag123sqlserver2008 ___ Verwenden Sie dieses Tag für Fragen, die für die 2008-Version von Microsoft SQL Server spezifisch sind. ___ tag123indexing ___ Indizierung von Datenstrukturen ist eine allgemeine Technik, um die Geschwindigkeit von Datensuchen zu verbessern. ___ qstntxt ___

Ich habe zwei Tabellen [LogTable] und [LogTable_Cross].

Im Folgenden finden Sie das Schema und das Skript zum Auffüllen:

%Vor%

Ich möchte alle diese Logs (aus LogTable) auswählen, die Benutzer-ID (Benutzer-ID wird von Kreuztabelle LogTable_Cross) mit Datesent Desc.

%Vor%

Nach dem Ausführen dieser Abfrage ist hier mein Ausführungsplan:

Wie Sie sehen können, kommt ein Sortieroperator in die Rolle, und das sollte wahrscheinlich wegen der folgenden Zeile "ORDER BY DateSent DESC"

sein

Meine Frage ist, warum dieser Sortieroperator in den Plan kommt, obwohl ich den folgenden Index auf die Tabelle angewendet habe

%Vor%

Wenn ich andererseits den Join entferne und die Abfrage auf diese Weise schreibe:

%Vor%

Der Plan ändert sich zu

d. h. Sortieroperator wird entfernt und der Plan zeigt an, dass meine Abfrage meinen nicht gruppierten Index verwendet.

Das ist also eine Möglichkeit, den Operator "Sortieren" im Plan für meine Abfrage zu entfernen, selbst wenn ich Join verwende.

BEARBEITEN :

Ich ging weiter und begrenzte den "Max Parallelitätsgrad" auf 1

Lief die folgende Abfrage erneut ab:

%Vor%

und der Plan hat immer noch diesen Sortieroperator:

Bearbeiten 2

Auch wenn ich den folgenden Index wie vorgeschlagen habe:

%Vor%

Der Plan hat immer noch den Sortieroperator:

    
___ tag123sqlserver2012 ___ Verwenden Sie dieses Tag für Fragen, die für die 2012 Version von Microsoft SQL Server spezifisch sind. ___ tag123databasetung ___ befasst sich mit der Optimierung der Leistung einer Datenbank. Es kann sich um den Dateientwurf und die Auswahl von DBMS, Betriebssystem und Plattform handeln. ___ answer43491344 ___

Sie haben eine Sortieroperation, wenn Sie den Join haben wegen der Parallelität in den vorherigen Schritten. Wenn SQL Server die Datensätze in mehreren Threads verarbeitet, wird die Reihenfolge nicht mehr bestimmt. Jeder Thread schiebt die Ergebnisse einfach an das nächste Element in der Pipeline (Hash-Match in Ihrem Fall).

Da die Reihenfolge nicht festgelegt ist und Sie eine Bestellung anfordern, muss SQL Server das Ergebnis sortieren.

Sie können versuchen, den %code% -Hinweis hinzuzufügen, um zu erzwingen, dass SQL Server die Abfrage nur mit einem Thread ausführt. Dies kann in diesem Fall hilfreich sein, kann aber auch zu Leistungseinbußen führen.

Die zweite Abfrage kann mit einem Index-Scan erfüllt werden, und der Index ist geordnet und die Reihenfolge ist die gleiche wie die angeforderte. Die Datensätze (Schlüssel) im Index werden per Definition sortiert. SQL Server vermutete, dass das Ausführen der Abfrage in einem Thread und das einfache Lesen der Daten mithilfe des Index vorteilhafter ist als das Lesen der Daten mithilfe mehrerer Threads und deren späterer Sortierung.

    
___
3
Antworten

Vermeiden Sie den Sortieroperator im Indexplan

Ich habe zwei Tabellen [LogTable] und [LogTable_Cross]. Im Folgenden finden Sie das Schema und das Skript zum Auffüllen: %Vor% Ich möchte alle diese Logs (aus LogTable) auswählen, die Benutzer-ID (Benutzer-ID wird von Kreuztabelle LogTabl...
19.04.2017, 08:54