Es gibt einen Clustered - Index auf einem Tisch Client
Feld LastName
.
Wenn ich einfach alle Datensätze aus der Tabelle speichere, werden sie in alphabetischer Reihenfolge angezeigt, sofern nicht (nolock)
wie in der betreffenden Abfrage ein Hinweis verwendet wird. Dieser Hinweis ändert die Reihenfolge der Datensätze. Sollte es?. Ich bin mir sicher, dass keine andere Sitzung eine offene Transaktion mit den Änderungen an dieser Tabelle hat (zumindest werden sp_who2
mir keine angezeigt).
Wie kann der Unterschied in der Reihenfolge erklärt werden?
Zusätzliche Informationen aus Kommentaren:
Es gibt keine Bestellung von. Sollte ein nicht gruppierter Index die Reihenfolge erzwingen?
Die Abfragen geben auch dann noch eine andere Reihenfolge zurück, wenn ein Indexhinweis verwendet wird, der einen Clustered-Index angibt. Sollten Sie? Ich frage mich, warum
nolock
sich die Reihenfolge der zurückgegebenen Datensätze ändert, ohne dass die Pläne sichtbar geändert werden.Ich habe ein WinDiff auf ihnen gemacht - dasselbe mit Ausnahme von [dem]
(nolock)
[ Abfragehinweis ].
Antworten:
Das Auftreten einer geordneten Ergebnismenge ohne
ORDER BY
Klausel resultiert häufig aus einem Scan, bei dem Zeilen in Indexreihenfolge abgerufen werden. Ein Grund, warum ein Scan in Indexreihenfolge im Allgemeinen unter der Standardisolationsstufe ausgewähltREAD COMMITTED
wird, besteht darin, dass die Wahrscheinlichkeit unerwünschter Parallelitätsanomalien verringert wird, z. B. das mehrfache Auftreten derselben Zeile oder das vollständige Überspringen einiger Zeilen. Dies wird an mehreren Stellen detailliert beschrieben, einschließlich in dieser Artikelserie über Isolationsstufen.Mit einem
NOLOCK
Tabellenhinweis wird dieses Verhalten gelockert, und der Zugriff auf die Tabelle erfolgt unter der toleranterenREAD UNCOMMITTED
Isolationsstufe, die Daten in Zuordnungsreihenfolge anstelle der Indexreihenfolge scannen kann . Wie in diesem Link beschrieben, bleibt die Entscheidung, ob ein Scan der Zuordnungsreihenfolge oder der Indexreihenfolge verwendet werden soll, der Speicher-Engine überlassen. Diese Auswahl kann zwischen Ausführungen ohne Änderung des Abfrageplans geändert werden .Dies mag sehr abstrakt klingen, kann jedoch mit einigen Abfragen mithilfe nicht dokumentierter Funktionen für die AdventureWorks2012-Datenbank einfacher demonstriert werden .
Die Anfragen wurden mit geringfügigen Änderungen von Paul White ausgeliehen .
Um ganz klar zu sein, handelt es sich bei dieser Antwort um das Erscheinungsbild einer geordneten Ergebnismenge. Es gibt keine garantierte Präsentationsreihenfolge ohne Top-Level
ORDER BY
.Ein Scan der Zuordnungsreihenfolge kann unter verschiedenen anderen Umständen erfolgen, z. B. wenn eine Sperre auf Tabellenebene erworben wird oder sich die Datenbank im schreibgeschützten Modus befindet. Parallelität kann auch die Reihenfolge beeinflussen, in der die Daten zurückgegeben werden. Der entscheidende Punkt ist, dass
ORDER BY
die Reihenfolge, in der die Daten zurückgegeben werden , ohne Design im Laufe der Zeit variieren kann.quelle
James hat gut erklärt, wie das funktioniert, aber ich möchte nur eines wiederholen: Wenn Sie keine Ordnungsfunktion verwenden, ist die Reihenfolge der Zeilen in der Ergebnismenge undefiniert . Wenn Sie eine bestimmte Reihenfolge benötigen, verwenden Sie eine explizite
order by
Klausel. Wenn Sie diese nicht angeben, sagen Sie im Grunde genommen "Die Reihenfolge ist mir überhaupt egal" und nicht "Sortieren nach dem Clustered-Index".quelle
... dann sollten Sie keine Bestellung erwarten. Tatsächlich kann dieselbe Abfrage, die mehrmals ausgeführt wird, ohne Vorwarnung in einer anderen Reihenfolge wiedergegeben werden. Der Grund dafür ist, dass Ihre beiden Abfragen - die höchstwahrscheinlich aufgrund des unterschiedlichen Abfragetextes und nicht aufgrund des Hinweises "unterschiedliche" Abfragen sind - unterschiedliche Ausführungspläne haben (und der Unterschied kann subtil sein, z. B. ein Iterator, der in gleich aussieht beide Pläne, hat aber
ordered: true
nur eine oder eine sehr unterschiedliche Anzahl geschätzter Zeilen, da eine vor einer größeren Datenänderung kompiliert wurde). Es könnte auch sein, dass ein Zuordnungsreihenfolge-Scan durchgeführt wird, wie James in seiner Antwort richtig dargelegt hat.Da Sie eine Abfrage ohne
ORDER BY
ausführen, schließt SQL Server auf jeden Fall, dass Sie sich nicht um die Reihenfolge kümmern, und ermittelt daher den effizientesten Weg, um die Zeilen zurückzugeben (wenn Sie dies nicht tun, ist die Reihenfolge nicht wichtig ).Lassen Sie mich das ganz klar machen:
Wenn Sie eine bestimmte Bestellung wünschen oder erwarten, fügen Sie eine ORDER BY-Klausel hinzu
Das ist schon mal aufgetaucht:
Und ich habe darüber gebloggt:
Hier ist ein Zitat aus letzterem, das wiederholt, was ich gesagt habe, um Ihren Kommentar zur Verwendung eines Indexhinweises anstelle einer
ORDER BY
Klausel anzusprechen :Conor Cunningham - ein ziemlich kluger Kerl, der direkt für vieles verantwortlich ist, was SQL Server tut, wenn es eine Abfrage für Sie verarbeitet - hat auch hier darüber gebloggt:
Bitte lesen Sie etwas und fügen Sie dann eine
ORDER BY
Klausel zu Ihren Abfragen hinzu, bevor Sie sich über eine andere oder unerwartete Sortierung beschweren.quelle