sql >> Base de Datos >  >> RDS >> Sqlserver

Orden de fila predeterminado en la consulta SELECT:SQL Server 2008 frente a SQL 2012

Debe volver atrás y agregar ORDER BY cláusulas a su código porque sin ellas nunca se garantiza el orden. Tuviste "suerte" en el pasado de que siempre recibiste el mismo pedido, pero no fue así porque SQL Server 2008 lo garantizaba de todos modos. Lo más probable es que tuviera que ver con sus índices o con la forma en que se almacenaban los datos en el disco.

Si se mudó a un nuevo host cuando actualizó, la diferencia en la configuración del hardware por sí sola podría haber cambiado la forma en que se ejecutan sus consultas. Sin mencionar el hecho de que el nuevo servidor habría vuelto a calcular las estadísticas en las tablas y el optimizador de consultas de SQL Server 2012 probablemente hace las cosas de manera un poco diferente a las de SQL Server 2008.

Es una falacia que pueda confiar en el orden de un conjunto de resultados en SQL sin indicar explícitamente el orden en el que lo desea. Los resultados de SQL NUNCA tenga un pedido en el que pueda confiar sin usar un ORDER BY cláusula. SQL se basa en la teoría de conjuntos. Los resultados de la consulta son básicamente conjuntos (o conjuntos múltiples).

Itzik Ben-Gan ofrece una buena descripción de la teoría de conjuntos en relación con SQL en su libro Microsoft SQL Server 2012 T-SQL Fundamentals

La teoría de conjuntos, que se originó con el matemático Georg Cantor, es una de las ramas matemáticas en las que se basa el modelo relacional. La definición de Cantor de un conjunto es la siguiente:

Por "conjunto" entendemos cualquier colección M en un todo de objetos definidos y distintos m (que se denominan los "elementos" de M) de nuestra percepción o de nuestro pensamiento. - Joseph W. Dauben y Georg Cantor (PrincetonUniversity Press, 1990)

Después de una explicación detallada de los términos en la definición, Itzik continúa diciendo:

Lo que la definición de conjunto de Cantor omite es probablemente tan importante como lo que incluye. Observe que la definición no menciona ningún orden entre los elementos del conjunto. El orden en que se enumeran los elementos del conjunto no es importante. La notación formal para enumerar elementos de conjuntos utiliza corchetes:{a, b, c}. Debido a que el orden no tiene relevancia, puede expresar el mismo conjunto que {b, a, c} o {b, c, a}. Saltando al conjunto de atributos (llamados columnas en SQL) que forman el encabezado de una relación (llamado tabla en SQL), se supone que un elemento se identifica por su nombre, no por su posición ordinal. De manera similar, considere el conjunto de tuplas (llamadas filas por SQL) que forman el cuerpo de la relación; un elemento se identifica por sus valores clave, no por su posición. A muchos programadores les cuesta adaptarse a la idea de que, con respecto a la consulta de tablas, no existe un orden entre las filas. En otras palabras, una consulta en una tabla puede devolver filas en cualquier orden a menos que solicite explícitamente que los datos se clasifiquen de una manera específica, tal vez con fines de presentación.

Pero independientemente de la definición académica de un conjunto, incluso la implementación en el servidor SQL nunca ha garantizado ningún orden en los resultados. Esta publicación de blog de MSDN de 2005 de un miembro del equipo del optimizador de consultas establece que no debe confiar en absoluto en el orden de las operaciones intermedias.

Las reglas de reordenación pueden violar y violarán esta suposición (y lo harán cuando no sea conveniente para usted, el desarrollador;). Por favor comprenda que cuando reordenamos las operaciones para encontrar un plan más eficiente, podemos hacer que el comportamiento de ordenamiento cambie para los nodos intermedios en el árbol. Si ha puesto una operación en el árbol que asume un orden intermedio particular, puede fallar.

Esta publicación de blog de Conor Cunningham (Arquitecto, SQL Server Core Engine) "Sin cinturón de seguridad - Esperando orden sin ORDEN POR" trata sobre SQL Server 2008. Tiene una tabla con 20k filas con un solo índice que parece devolver siempre filas en el mismo orden. Agregando un ORDER BY a la consulta ni siquiera cambia el plan de ejecución, por lo que no es como si agregar uno hiciera que la consulta fuera más costosa si el optimizador se da cuenta de que no la necesita. Pero una vez que agrega otras 20k filas a la tabla, de repente el plan de consulta cambia y ahora usa paralelismo y ¡los resultados ya no están ordenados!

La parte difícil aquí es que no existe una forma razonable para que un usuario externo sepa cuándo cambiará un plan. El espacio de todos los planes es enorme y duele la cabeza reflexionar. El optimizador de SQL Server cambiará los planes, incluso para consultas simples, si cambian suficientes parámetros. Puede tener suerte y no tener un cambio de plan, o simplemente no puede pensar en este problema y agregar un ORDEN POR.

Si necesita más convencimiento, solo lea estas publicaciones:

  • Sin ORDER BY, no hay orden de clasificación predeterminado. - Alexander Kuznetsov
  • ¡Orden en la corte! - Thomas Kyte
  • Orden de un conjunto de resultados en SQL - Timothy Wiseman