Por qué SQL Server no garantiza resultados de ordenación sin ORDER BY

Hola de nuevo. En junio, OTUS lanza nuevamente el curso "Desarrollador MS SQL Server" , tradicionalmente en la víspera del comienzo del curso, comenzamos a compartir material sobre el tema con usted.




Si su consulta no contiene ORDER BY, no puede estar seguro de que la clasificación de los resultados no cambiará con el tiempo.

Por supuesto, al principio todo será bastante predecible, pero a medida que ocurran cambios (en índices, tablas, configuración del servidor, cantidad de sus datos), puede encontrar algunas sorpresas desagradables.

Comencemos con algo simple: haga un SELECCIONAR para la tabla Usuarios de la base de datos de Desbordamiento de pila. Esta tabla tiene un índice de clúster para la columna Id, que comienza desde uno y aumenta a un billón. Para esta consulta, los datos se devuelven en el orden del índice agrupado:



Pero si crea un índice en DisplayName y Location, SQL Server de repente decide usar un nuevo índice, no uno agrupado:



Aquí está el plan de ejecución:



Por qué SQL Server decidió usar este índice, aunque no necesitaba ser ordenado por DisplayName y ubicación? Porque este índice es la copia más pequeña de los datos que debe obtenerse. Veamos el tamaño de los índices con sp_BlitzIndex:



El índice agrupado (CX / PK) tiene aproximadamente 8,9 millones de filas y su tamaño es de 1,1 GB .

En el índice no agrupado para DisplayName, la ubicación también es de aproximadamente 8,9 millones de filas, pero su tamaño es de solo 368 MB . Si necesita hacer un análisis para obtener los resultados de la consulta, ¿por qué no elegir la fuente de datos más pequeña, ya que será más rápida? Es por esta razón que SQL Server hizo esto.

"Sí, pero mi solicitud contiene DONDE".


Ok, ahora que tenemos un índice para DisplayName y Location, intentemos una consulta que busque un nombre específico (DisplayName). Los resultados se ordenan por DisplayName:



el plan de ejecución muestra que DisplayName y Location utilizan el índice:



pero si observa un valor diferente, los resultados ya no se ordenarán por DisplayName:



SQL Server descubrió que Alex tiene un índice agrupado mucho más razonable Escanear en lugar de Búsqueda de índice + Búsqueda de clave:



incluso en estos casos realmente simples, no puede garantizar que SQL Server siempre use la copia de datos que espera.

Recientemente, me he encontrado con casos mucho más complicados:

  • Eliminar el índice utilizado en la consulta
  • (Forced Parameterization), , SQL Server
  • (Compatibility Level) (Cardinality Estimator), .



.



All Articles