¿Por qué ORDER BY no pertenece a una vista?

51

Me entender que no se puede tener ORDER BY en una vista. (Al menos en SQL Server 2012 estoy trabajando)

También entiendo que la forma "correcta" de ordenar una vista es colocar una declaración ORDER BYalrededor de SELECTla vista que consulta la vista.

Pero siendo relativamente nuevo en el SQL práctico y en el uso de las vistas, me gustaría entender por qué esto se hace por diseño. Si he seguido el historial correctamente, esto fue posible una vez y se eliminó explícitamente de SQL Server 2008, etc. (no me cite la versión exacta).

Sin embargo, la mejor razón por la que se me ocurre por qué Microsoft eliminó esta característica es porque "una vista es una recopilación de datos sin clasificar".

Supongo que hay una buena razón lógica de por qué una vista debe estar sin clasificar. ¿Por qué una vista no puede ser simplemente una colección de datos aplanada? ¿Por qué específicamente sin clasificar? No parece tan difícil encontrar situaciones en las que (al menos para mí / en mi humilde opinión) parezca perfectamente intuitivo tener una vista ordenada.

ngmiceli
fuente
2
La primera respuesta es perfecta. Sugeriría si desea ordenar una vista, ¿por qué no hace esto? Seleccione [Columnas] de [YourView] Ordenar por [Columnas]
Zane
Respuesta corta: "Por la misma razón que ORDER BY no pertenece a una tabla".
ypercubeᵀᴹ

Respuestas:

38

(Vistas indizadas a un lado, por supuesto).

Una vista no se materializa: los datos no se almacenan, entonces, ¿cómo se podrían ordenar? Una vista es como un procedimiento almacenado que solo contiene un SELECTsin parámetros ... no contiene datos, solo contiene la definición de la consulta. Dado que las diferentes referencias a la vista pueden necesitar datos ordenados de diferentes maneras, la forma en que lo hace, al igual que seleccionar de una tabla, que también es una colección no clasificada de filas, por definición, es incluir el orden en la consulta externa .

También para dar una pequeña idea de la historia. Se podía nunca se puso ORDER BYen una vista, sin que también incluye TOP. Y en este caso, ORDER BYdictaban qué filas se incluían TOP, no cómo se presentarían. Dio la casualidad de que en SQL Server 2000, si TOPera 100 PERCENTo {some number >= number of rows in the table}, el optimizador era bastante simplista y terminó produciendo un plan con un tipo que coincidía con el TOP/ORDER BY. Pero este comportamiento nunca se garantizó ni se documentó, solo se basó en la observación, que es un mal hábito . Cuando salió SQL Server 2005, este comportamiento comenzó a "romperse" debido a los cambios en el optimizador que llevaron a la utilización de diferentes planes y operadores, entre otras cosas,TOP / ORDER BYsería ignorado por completo si lo fuera TOP 100 PERCENT. Algunos clientes se quejaron de esto tan fuerte que Microsoft emitió un indicador de rastreo para restablecer el comportamiento anterior. No voy a decirte cuál es el indicador porque no quiero que lo uses y quiero asegurarme de que la intención sea correcta; si quieres un orden de clasificación predecible, úsalo ORDER BYen la consulta externa.

Para resumir y para aclarar un punto que hizo: Microsoft no eliminó nada. Mejoraron el producto y, como efecto secundario, este comportamiento indocumentado y no garantizado se volvió menos confiable. En general, creo que el producto es mejor para él.

Aaron Bertrand
fuente
Aquí se menciona (en un comentario) que TOPrealiza una operación de cursor sobre el conjunto de resultados. Por lo tanto, puede tener un orden explícito.
Tim Schmelter
@TimSchmelter que no ayuda cuando el optimizador lo ve TOP 100 PERCENT / ORDER BYy lo elimina completamente del plan. Pruébalo.
Aaron Bertrand
Fue solo una nota al margen. De todos modos, el resto del comentario es el siguiente: "el truco SELECT TOP x está desaprobado en una versión futura de SQL Server, por lo que sería mejor no usarlo en absoluto".
Tim Schmelter
@TimSchmelter ya no funciona. No creo que deje de funcionar en ninguna versión nueva en el corto plazo, porque romperá demasiado código existente.
Aaron Bertrand
2
@TimSchmelter allí orden no está hablando del orden de las filas, está hablando del orden de las columnas dentro de una fila. En SQL Server generalmente no hablamos de que una fila sea una tupla porque la implementación física de una fila es muy obvia para nosotros (la tabla enumera las columnas en el orden en que las definió).
Aaron Bertrand
9

Si se permitió ordenar una vista, ¿cuál debería ser el orden del resultado aquí?

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
fuente
No entiendo este punto. En lugar de escribir una vista de base de datos, puede escribir una consulta SQL normal. Entonces, ¿cuál debería ser el orden del resultado en ese caso? gracias
hqt
7

una posibilidad es evitar tipos conflictivos: si la vista está ordenando por un orden y la selección en esa vista está ordenando por otro orden (sin tener en cuenta el orden de la vista), puede haber un impacto en el rendimiento. Por lo tanto, es más seguro dejar el requisito de clasificación al usuario.

Otra razón, la ordenación conlleva un costo de rendimiento, entonces, ¿por qué penalizar a todos los usuarios de la vista, cuando solo algunos usuarios necesitan la ordenación?

srini.venigalla
fuente
5

ANSI SQL solo permite la ORDER BYconsulta externa por una variedad de razones, una de las cuales sucede cuando una subselección / vista / CTE se une a otra tabla y la consulta externa tiene una ORDER BYpropia.

El servidor SQL nunca lo admitió dentro de una vista (a menos que lo haya engañado usando uno TOP 100 PERCENTque, en mi opinión, está desencadenando un error).

Incluso si activó el error, los resultados nunca han sido confiables, y la clasificación no siempre salió como esperaba.

Consulte esta publicación de blog del equipo del Optimizador de consultas para obtener una explicación técnica completa. TOP 100 POR CIENTO PEDIDO POR Considerado nocivo.

La implementación del plan predeterminado para este código sucede para ordenar las filas como parte de la realización de la operación TOP. A menudo, esto significaba que los resultados se devolvían en orden ordenado, y esto hacía que los clientes creyeran que había una garantía de que las filas estaban ordenadas. Este no es realmente el caso. Si desea que las filas se devuelvan al usuario en orden ordenado, debe usar un ORDER BY en el bloque de consulta más externo (según ANSI) para garantizar el orden de presentación de salida.

Tom V
fuente
3

Las vistas se comportan como tablas cuyo contenido está determinado por los resultados de una consulta.

Las tablas no tienen orden; son solo bolsas de hileras.

Por lo tanto, las vistas tampoco tienen orden. Sin embargo, puede ordenarlos seleccionando filas en un ORDEN particular.

al anochecer
fuente
1
Tablas ... son sólo bolsas de filas - y luego viwes son sólo virtuales bolsas de virtuales filas - vistas "no existen" - por ejemplo, no hay datos almacenados para ellos en absoluto - que son sólo "definiciones almacenadas de una consulta a ser ejecutado ", básicamente.
marc_s
1
+1 La equivalencia de tabulaciones y puntos de vista me parece la razón principal por la cual los puntos de vista no deben contener un "orden de"
miracle173
1
"Las vistas se comportan como tablas" . Yo diría que "Las vistas se comportan como tablas base. Las vistas son tablas".
ypercubeᵀᴹ
-2

Una respuesta que aún no se ha dado es que "ordenar por" puede interferir con el empuje de predicados, lo que puede afectar en gran medida el rendimiento.

Un ejemplo es tener una vista que acumula un gran conjunto de datos en un resumen de 10 líneas que está entre los 10 primeros / ordenados:

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

Para el mismo caso con un predicado fuerte:

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

Todavía lleva la misma cantidad de tiempo porque el orden superior está bloqueando la ejecución del predicado antes en la tubería. Esto puede causar que se procesen filas innecesarias y el plan será similar al que no tiene un predicado.

Si el impulso debe ocurrir antes del pedido es realmente una elección del desarrollador y puede cambiar la respuesta. Muy a menudo, el impulso es la intención lógica.

El uso del "100 por ciento superior" lógicamente permite el empuje de predicados, sin embargo, la implementación desafortunadamente ignora "ordenar por" para este caso y anula la intención.

Para casos de uso real, un buen compromiso sería que el motor realizara "orden tirando". Esto permitiría especificar un "orden por" dentro de la vista (con el 100 por ciento superior o sin superior) y ese orden solo se usa si la vista se selecciona directamente, sin un orden explícito por, sin uniones, sin agregados, sin ver encadenamiento, etc. Ambos casos enumerados anteriormente podrían ser compatibles con este modelo simple.

crokusek
fuente
-6

puede crear una vista que tenga orden por y conserve el orden por cuando se le consulta después de:

seleccione el 99.999999999999 por ciento superior * de ..... ordene por

NasF1
fuente
1
¿Por qué no solo SELECT TOP 100 PERCENT ...?
Max Vernon
2
@Max probablemente similar a este truco , eso no lo convierte en una buena idea.
Aaron Bertrand
De acuerdo, @AaronBertrand - solo señalando que no hay necesidad de usar 99.99999999999 :-)
Max Vernon