Warum gehört ORDER BY nicht in eine Ansicht?

51

Ich verstehe, dass Sie nicht ORDER BY in einer Ansicht haben können. (Zumindest in SQL Server 2012 arbeite ich mit)

Ich verstehe auch, dass die "richtige" Art, eine Ansicht zu sortieren, darin besteht, ORDER BYdie SELECTAnweisung, die die Ansicht abfragt , mit einem Zirkel zu versehen.

Da ich jedoch relativ neu in der SQL-Praxis und in der Verwendung von Ansichten bin, möchte ich verstehen, warum dies so beabsichtigt ist. Wenn ich den Verlauf korrekt verfolgt habe, war dies einmal möglich und wurde explizit aus SQL Server 2008 usw. entfernt (zitieren Sie mich nicht in der genauen Version).

Der beste Grund, warum Microsoft diese Funktion entfernt hat, ist "eine Ansicht ist eine unsortierte Sammlung von Daten".

Ich gehe davon aus, dass es einen guten, logischen Grund gibt, warum eine Ansicht unsortiert sein sollte. Warum kann eine Ansicht nicht einfach eine abgeflachte Datensammlung sein? Warum gerade un -sortierte? Es scheint nicht so schwer zu sein, Situationen zu finden, in denen es (zumindest für mich / IMHO) vollkommen intuitiv erscheint, eine sortierte Ansicht zu haben.

ngmiceli
quelle
2
Die erste Antwort ist perfekt. Ich würde vorschlagen, wenn Sie eine Ansicht bestellen möchten, warum tun Sie dies nicht einfach. Wählen Sie [Columns] aus [YourView] Order By [Columns]
Zane
Kurze Antwort: "Aus dem gleichen Grund, dass ORDER BY nicht zu einer Tabelle gehört."
ypercubeᵀᴹ

Antworten:

38

(Abgesehen von indizierten Ansichten.)

Eine Ansicht wird nicht materialisiert - die Daten werden nicht gespeichert. Wie können sie also sortiert werden? Eine Ansicht ähnelt einer gespeicherten Prozedur, die nur eine SELECTohne Parameter enthält. Sie enthält keine Daten, sondern nur die Definition der Abfrage. Da unterschiedliche Verweise auf die Ansicht möglicherweise Daten benötigen, die auf unterschiedliche Weise sortiert sind, müssen Sie bei dieser Vorgehensweise - genau wie bei der Auswahl aus einer Tabelle, bei der es sich definitionsgemäß auch um eine unsortierte Auflistung von Zeilen handelt - die Reihenfolge von in die äußere Abfrage aufnehmen .

Auch um einen kleinen Einblick in die Geschichte zu geben. Man konnte nie setzen , ORDER BYohne darunter auch in einer Ansicht TOP. Und in diesem Fall wurde ORDER BYdiktiert, von welchen Zeilen sie aufgenommen wurden TOP, und nicht, wie sie dargestellt würden. Es ist einfach so passiert , dass in SQL Server 2000, wenn TOPwar 100 PERCENToder {some number >= number of rows in the table}der Optimierer ziemlich simpel war und es endete , einen Plan mit einer Art erzeugen , die die abgestimmt TOP/ORDER BY. Dieses Verhalten wurde jedoch nie garantiert oder dokumentiert - es beruhte lediglich auf Beobachtungen, was eine schlechte Angewohnheit ist . Als SQL Server 2005 herauskam, begann dieses Verhalten aufgrund von Änderungen im Optimierungsprogramm, die dazu führten, dass verschiedene Pläne und Operatoren verwendet wurden, zu "brechen"TOP / ORDER BYwürde völlig ignoriert werden, wenn es wäre TOP 100 PERCENT. Einige Kunden haben sich darüber so laut beschwert, dass Microsoft ein Ablaufverfolgungsflag ausgegeben hat, um das alte Verhalten wiederherzustellen. Ich werde Ihnen nicht sagen, was das Flag ist, weil ich nicht möchte, dass Sie es verwenden, und ich möchte sicherstellen, dass die Absicht richtig ist - wenn Sie eine vorhersehbare Sortierreihenfolge wünschen, verwenden Sie ORDER BYfür die äußere Abfrage.

Um einen Punkt zusammenzufassen und zu verdeutlichen: Microsoft hat nichts entfernt . Sie machten das Produkt besser und als Nebeneffekt wurde dieses undokumentierte, nicht garantierte Verhalten weniger zuverlässig. Insgesamt finde ich das Produkt besser dafür.

Aaron Bertrand
quelle
Hier wird (in einem Kommentar) erwähnt, dass der TOPCursor eine Operation über der Ergebnismenge ausführt. Dafür kann es eine explizite Bestellung geben.
Tim Schmelter
@TimSchmelter, das nicht hilft, wenn der Optimierer es sieht TOP 100 PERCENT / ORDER BYund vollständig aus dem Plan entfernt. Versuch es.
Aaron Bertrand
Es war nur eine Nebenbemerkung. Der Rest des Kommentars lautet auf jeden Fall wie folgt: "Der SELECT TOP x-Trick wird in einer zukünftigen Version von SQL Server voraussichtlich nicht mehr unterstützt. Daher ist es am besten, ihn überhaupt nicht zu verwenden."
Tim Schmelter
@ TimSchmelter es ist schon ein No-Op. Ich denke nicht, dass es in absehbarer Zeit in einer neuen Version nicht mehr funktionieren wird, da zu viel vorhandener Code beschädigt wird.
Aaron Bertrand
2
@TimSchmelter Bei der Reihenfolge handelt es sich nicht um die Reihenfolge der Zeilen, sondern um die Reihenfolge der Spalten in einer Zeile. In SQL Server wird im Allgemeinen nicht davon gesprochen, dass eine Zeile ein Tupel ist, da die physische Implementierung einer Zeile für uns so offensichtlich ist (in der Tabelle sind die Spalten in der Reihenfolge aufgeführt, in der Sie sie definiert haben).
Aaron Bertrand
9

Wenn eine Ansicht sortiert werden durfte, in welcher Reihenfolge sollte das Ergebnis hier sein?

CREATE VIEW dbo.V1
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number ASC

GO

CREATE VIEW dbo.V2
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number DESC

GO

SELECT *
FROM   dbo.V1
       JOIN dbo.V2
         ON V1.number = V2.number 
Martin Smith
quelle
Ich verstehe diesen Punkt nicht. Anstatt die Datenbankansicht zu schreiben, können Sie auch normale SQL-Abfragen schreiben. Wie sollte die Reihenfolge des Ergebnisses in diesem Fall sein? danke
hqt
7

Eine Möglichkeit besteht darin, widersprüchliche Sortierungen zu vermeiden. Wenn die Ansicht nach einer Reihenfolge sortiert wird und die Auswahl in dieser Ansicht nach einer anderen Reihenfolge sortiert wird (da die Ansichtssortierung nicht bekannt ist), kann dies zu Leistungseinbußen führen. Es ist also sicherer, die Sortieranforderung dem Benutzer zu überlassen.

Ein weiterer Grund ist, dass sort mit Performance-Kosten verbunden ist. Warum also alle Benutzer der Ansicht benachteiligen, wenn nur einige Benutzer die Sortierung benötigen?

srini.venigalla
quelle
5

ANSI SQL lässt die ORDER BYäußerste Abfrage aus verschiedenen Gründen nur zu. Eine davon ist, wenn eine Unterauswahl / Ansicht / CTE mit einer anderen Tabelle verknüpft wird und die äußere Abfrage eine eigene ORDER BYhat.

SQL Server hat es in einer Ansicht nie unterstützt (es sei denn, Sie haben es mit einem ausgetrickst, TOP 100 PERCENTder meiner Meinung nach meistens einen Fehler auslöst).

Selbst wenn Sie den Fehler ausgelöst haben, waren die Ergebnisse nie zuverlässig, und die Sortierung verlief nicht immer so, wie Sie es erwartet hatten.

In diesem Blog-Beitrag des Query Optimizer-Teams finden Sie eine vollständige technische Erklärung. TOP 100 Prozent BESTELLUNG NACH Als schädlich eingestuft.

Die Standardplanimplementierung für diesen Code sortiert die Zeilen im Rahmen der Ausführung der TOP-Operation. Oft bedeutete dies, dass die Ergebnisse in sortierter Reihenfolge zurückgegeben wurden, und dies veranlasste die Kunden zu der Annahme, dass eine Garantie für die Sortierung der Zeilen bestand. Das ist eigentlich nicht der Fall. Wenn Sie möchten, dass Zeilen in sortierter Reihenfolge an den Benutzer zurückgegeben werden, müssen Sie ein ORDER BY für den äußersten Abfrageblock (gemäß ANSI) verwenden, um die Ausgabereihenfolge der Präsentation zu gewährleisten.

Tom V
quelle
3

Views verhalten sich wie Tabellen, deren Inhalt durch die Ergebnisse einer Abfrage bestimmt wird.

Tische haben keine Ordnung; Es sind nur Säcke mit Reihen.

Daher haben Ansichten auch keine Reihenfolge. Sie können sie jedoch sortieren, indem Sie Zeilen in einer bestimmten Reihenfolge auswählen.

duskwuff
quelle
1
Tabellen ... sind nur Taschen voller Zeilen - und viwes sind dann nur virtuelle Taschen voller virtueller Zeilen - Ansichten "existieren nicht" - z. B. sind für sie überhaupt keine Daten gespeichert - sie sind nur "gespeicherte Definitionen einer Abfrage" ausgeführt werden ", im Grunde.
Marc_s
1
+1 Die Gleichwertigkeit von Tabellen und Ansichten scheint mir der Hauptgrund zu sein, warum Ansichten keine "Bestellung von" enthalten sollten
miracle173
1
"Views verhalten sich wie Tabellen" . Ich würde sagen, dass "Views sich wie Basistabellen verhalten. Views sind Tabellen."
Ypercubeᵀᴹ
-2

Eine noch nicht gegebene Antwort ist, dass "order by" das Prädikat-Pushing stören kann, was die Leistung stark beeinträchtigen kann.

Ein Beispiel ist eine Ansicht, die eine große Menge von Daten in einer 10-zeiligen Zusammenfassung zusammenfasst, die unter den Top 10 / Geordnet steht:

select * from TopOrderedView; -- Ordered 10 line summary in 5s

Für den gleichen Fall mit einem starken Prädikat:

select * from TopOrderedView where <condition>; -- Ordered 2 line summary in still 5s

Es dauert immer noch genauso lange, da das Prädikat durch top / order by daran gehindert wird, früher in der Pipeline ausgeführt zu werden. Dies kann dazu führen, dass nicht benötigte Zeilen verarbeitet werden, und der Plan ähnelt dem ohne Prädikat.

Ob der Push vor der Bestellung von passieren soll, ist wirklich eine Entwicklerentscheidung und kann die Antwort ändern. Am häufigsten ist der Push die logische Absicht.

Die logische Verwendung von "top 100 percent" ermöglicht das Pushen von Prädikaten, die Implementierung ignoriert jedoch in diesem Fall leider "order by" und besiegt die Absicht.

Für echte Anwendungsfälle wäre es ein guter Kompromiss, wenn der Motor "Order by Pulling" ausführt. Auf diese Weise kann in der Ansicht eine "Reihenfolge nach" angegeben werden (mit einem Top-100-Prozent-Wert oder ohne Top-Wert). Diese Reihenfolge wird nur verwendet, wenn die Ansicht direkt ausgewählt wird, ohne eine explizite Reihenfolge nach, ohne Joins, ohne Aggregate und ohne Ansichtsverkettung usw. Beide oben aufgeführten Fälle könnten von diesem einfachen Modell unterstützt werden.

crokusek
quelle
-6

Sie können eine Ansicht erstellen, die die Reihenfolge von hat und die Reihenfolge von beibehält, wenn sie abgefragt wird nach:

select top 99.999999999999 Prozent * from ..... order by

NasF1
quelle
1
Warum nicht einfach SELECT TOP 100 PERCENT ...?
Max Vernon
2
@Max wahrscheinlich ähnlich wie dieser Trick - das macht es keine gute Idee.
Aaron Bertrand
Einverstanden, @AaronBertrand - nur zur Kenntnis, dass es nicht nötig ist, 99.99999999999 zu verwenden :-)
Max Vernon