Warum fügt SSMS neue Zeilen oben in eine Tabelle ein, nicht unten?

14

Immer wenn ich in SQL Server Management Studio 2008 eine Zeile manuell in eine Tabelle einfüge (die Datenbank ist SQL Server 2005), wird meine neue Zeile oben in der Liste und nicht unten angezeigt. Ich verwende Identitätsspalten und dies führt zu Dingen wie

id  row
42 first row
1 second row
2 third row

Wenn Zeilen abgerufen und nicht explizit geordnet werden. Dies führt zu einer anderen Darstellung, wenn die Zeilen für die Webanwendung abgerufen werden, und ändert, was eine TOP 1Abfrage zurückgibt.

Ich weiß, ich kann order bysie, aber warum passiert das? Die meisten meiner Daten werden über eine Webanwendung eingefügt. Alle Einfügungen aus dieser Anwendung führen zu einer First-In-First-Out-Bestellung, z. Befindet sich auf dem Server oder im Management Studio eine Einstellung, die diese falsche Reihenfolge verursacht?

Ben Brocka
quelle
Wie ich manchmal gesehen habe, hängt es von der Reihenfolge der PK ab, wie die Zeilen angezeigt werden, wenn Sie eine einzelne Tabelle auswählen. Wenn Sie einige Verknüpfungen vornehmen, kann es je nach den anderen Tabellen PK, FK und Indizes ändern ...
Guillermo Gutiérrez
Achten Sie auch auf Karussellscans .
Michael Green

Antworten:

21

In der SQL-Welt ist die Reihenfolge keine inhärente Eigenschaft einer Datenmenge. Daher erhalten Sie von Ihrem RDBMS keine Garantie dafür, dass Ihre Daten in einer bestimmten Reihenfolge - oder sogar in einer konsistenten Reihenfolge - zurückkehren, es sei denn, Sie fragen Ihre Daten mit einer ORDER BYKlausel ab.

Von Craig Freedman :

Die Kombination von TOP mit ORDER BY fügt der Menge der zurückgegebenen Zeilen Determinismus hinzu. Ohne ORDER BY hängt die Menge der zurückgegebenen Zeilen vom Abfrageplan ab und kann sogar von Ausführung zu Ausführung variieren.

Verwenden ORDER BYSie diese Option immer, wenn Sie eine klar definierte und konsistente Reihenfolge in Ihrer Ergebnismenge erwarten. Verlassen Sie sich niemals darauf, wie Ihre Datenbank die Zeilen auf der Festplatte speichert (z. B. über einen Clustered-Index), um eine bestimmte Reihenfolge der Daten in Ihren Abfragen zu gewährleisten.

Nick Chammas
quelle
13

Nur um die anderen Antworten zu ergänzen: Eine Tabelle ist per Definition eine ungeordnete Menge von Zeilen. Wenn Sie keine ORDER BYKlausel angeben , kann SQL Server die Zeilen in der Reihenfolge zurückgeben, die er für am effizientesten hält. Dies fällt häufig nur mit der Reihenfolge des Einfügens zusammen, da die meisten Tabellen einen Clustered-Index für Identität, Datum und Uhrzeit oder andere monoton ansteigende Spalten aufweisen. Sie sollten dies jedoch genau so behandeln: ein Zufall. Es kann sich mit neuen Daten, einer Statistikaktualisierung, einem Ablaufverfolgungsflag, Änderungen an maxdop, Abfragehinweisen, Änderungen an der Verknüpfung oder Where-Klauseln in der Abfrage, Änderungen am Optimierer aufgrund eines Service Packs / kumulativen Updates / Hotfixes / Upgrades ändern. Verschieben der Datenbank auf einen anderen Server usw. usw.

Mit anderen Worten, und ich weiß, dass Sie die Antwort bereits kennen, aber es kann nicht genug gesagt werden:

Wenn Sie sich auf die Reihenfolge einer Abfrage verlassen möchten, fügen Sie IMMER hinzu ORDER BY .

Aaron Bertrand
quelle
Ich hatte nicht vor, je nach Bestellung, aber optisch ist es ein bisschen ärgerlich, dass meine zuletzt eingefügten Artikel plötzlich oben sind.
Ben Brocka
Ich nehme an, das liegt daran, dass Sie Open Table verwenden. In Management Studio 2008 wurde dieser Befehl in "Edit Top n Rows" und "Select Top N Rows" aufgeteilt. Wenn Sie letztere auswählen, können Sie die resultierende Abfrage bearbeiten, z. B. die oberste entfernen und eine Bestellung hinzufügen durch.
Aaron Bertrand
Es ist Management Studio 2008, der Server ist 2005, sollte klarer sein. Ich wusste nicht, dass es einen "Open Table" -Befehl gibt, ich habe immer die selectAnweisungen verwendet
Ben Brocka
4
Ok, Punkt steht noch, ich verstehe, dass es ärgerlich ist, dass die Daten in einer Reihenfolge zurückkommen, die Sie nicht erwarten, aber ich hoffe, es ist jetzt klar, warum SQL Server sich nicht wirklich darum kümmert, welche Reihenfolge Sie erwarten, es sei denn, Sie sagen, dass es Ihnen wichtig ist durch Hinzufügen einer order by-Klausel. :-)
Aaron Bertrand
1

Dies liegt daran, dass die Tabelle (höchstwahrscheinlich) eine Heap-Tabelle ist und nicht indiziert ist. Machen Sie die ID-Spalte a PRIMARY KEYsowie IDENTITY. SQL Server speichert die Daten physisch basierend auf den Indizes. Wenn id beispielsweise ein Clustered-Index (wie ein Primärschlüssel) wäre, würden die Daten physisch in der Reihenfolge der IDs gespeichert und auf diese Weise auch ohne eine Abfrage zurückgegeben eine ORDER BYKlausel. Andernfalls ist die Reihenfolge der Zeilen für die Datenbank überhaupt nicht wichtig. Folglich ist es keine gute Praxis , eine Anwendung von der Reihenfolge der Zeilen in der Datenbank abhängig zu machen (und auch davon, ob sich die Spalten in einer bestimmten Reihenfolge befinden). Die Anwendung muss mit allen Schlüsseln arbeiten, die sich in der Datenbank befinden, um Zeilen zu identifizieren.

Wil
quelle
Gut zu wissen. Ich wusste, dass dies ein Hinweis darauf ist, die zu verwendende App zu ändern order by(es ist eine vererbte App mit vielen schlechten Praktiken), aber ich habe mich genau gefragt, warum dies passiert ist.
Ben Brocka
5
Ändern Sie die Struktur der Tabelle nur so , dass SELECT *ohne ORDER BY vielleicht wieder in der „richtigen“ Reihenfolge (aber noch nicht garantiert werden)?
Aaron Bertrand
Bei einem einfachen SELECT aus der Tabelle mit einem Clustered-Index würde dies in der Reihenfolge des Clustered-Index erfolgen. War nicht so klar, wie ich hätte sein sollen, dass es sich um ein Beispiel dafür handelt, wann Daten physisch nach einer bestimmten Spalte geordnet sind, aber es ist definitiv nicht selbstverständlich, dass sie in jeder Abfrage korrekt zurückgegeben werden. Mea culpa.
Wil
5
Es spielt keine Rolle, wie der Clustered-Index lautet. SQL Server gibt möglicherweise die Reihenfolge basierend auf einem anderen Index zurück, der auf einer Vielzahl von Faktoren basiert. Das Erstellen eines Primärschlüssels für eine Spalte garantiert NICHT , dass Auswahlen ohne Reihenfolge von plötzlich immer nach dieser Spalte sortiert zurückkehren. Könnten Sie das die meiste Zeit beobachten? Sicher. Dies ist jedoch nicht gleichbedeutend mit einer Garantie. Ich habe noch nie einen Eisbären auf meiner Straße gesehen, aber es gibt kein Eisbär-Kraftfeld, das dies verhindert.
Aaron Bertrand
4
Mein Punkt war jedenfalls, dass das Hinzufügen einer ORDER BYKlausel eine viel bessere Garantie ist (egal, dass es weniger störend ist), als Schemaänderungen an der Tabelle vorzunehmen und zu hoffen, dass die Reihenfolge für immer so ist, wie Sie es erwarten.
Aaron Bertrand