Hay un índice agrupado en un Client
campo de tabla LastName
.
Cuando simplemente vuelco todos los registros de la tabla, aparecen en orden alfabético a menos que (nolock)
se use una pista como en la consulta en cuestión. Esa pista cambia el orden de los registros. ¿Deberia?. Estoy seguro de que ninguna otra sesión tiene una transacción abierta con los cambios en esa tabla (al menos sp_who2
no me muestra ninguna).
¿Cómo se puede explicar la diferencia en el orden?
Información adicional extraída de los comentarios:
No hay orden por. ¿Debería el índice no agrupado imponer el orden?
Las consultas aún devuelven un orden diferente incluso cuando se utiliza una sugerencia de índice que especifica un índice agrupado. ¿Deberían ellos? Me pregunto por qué
nolock
cambia el orden de los registros devueltos sin un cambio visible de los planes.Hice un WinDiff en ellos, lo mismo a excepción de [la]
(nolock)
[sugerencia de consulta].
Respuestas:
La aparición de un conjunto de resultados ordenado, sin una
ORDER BY
cláusula, a menudo resulta de un escaneo que recupera filas en orden de índice. Una razón por la que generalmente se elige una exploración de orden de índice bajo elREAD COMMITTED
nivel de aislamiento predeterminado es que reduce las posibilidades de anomalías de concurrencia no deseadas, como encontrar la misma fila varias veces o omitir por completo algunas filas. Esto se detalla en varios lugares, incluso en esta serie de artículos sobre niveles de aislamiento.Con una
NOLOCK
sugerencia de tabla, este comportamiento es relajado y el acceso a la tabla se realiza bajo elREAD UNCOMMITTED
nivel de aislamiento más tolerante , que puede escanear datos en orden de asignación en lugar de orden de índice. Como se describe en ese enlace, la decisión sobre si utilizar una exploración de orden de asignación o de orden de índice se deja al motor de almacenamiento. Esta opción puede cambiar entre ejecuciones sin un cambio en el plan de consulta .Esto puede sonar muy abstracto, pero se puede demostrar más fácilmente con algunas consultas utilizando funciones no documentadas en la base de datos AdventureWorks2012 .
Las consultas se toman prestadas con una ligera modificación de Paul White .
Finalmente, para ser claros, esta respuesta trata sobre la apariencia de un conjunto de resultados ordenado. No hay orden de presentación garantizada sin un nivel superior
ORDER BY
.Una exploración de orden de asignación puede ocurrir en una variedad de otras circunstancias, como cuando se adquiere un bloqueo a nivel de tabla o la base de datos está en modo de solo lectura. El paralelismo también puede influir en el orden en que se devuelven los datos. El punto clave es que sin ellos
ORDER BY
, los datos de los pedidos devueltos pueden variar con el tiempo según el diseño.fuente
James explicó muy bien cómo funciona esto, pero solo me gustaría reiterar una cosa: a menos que use una función de orden, el orden de las filas en el conjunto de resultados no está definido . Si necesita un pedido determinado, use una
order by
cláusula explícita : si no lo especifica, básicamente está diciendo "No me importa el orden en absoluto", no "Ordenarlo por el índice agrupado".fuente
... entonces no deberías esperar ningún pedido. De hecho, la misma consulta ejecutada varias veces podría volver en un orden diferente sin previo aviso. La razón es que sus dos consultas, que son consultas "diferentes" probablemente debido al texto de consulta diferente, no debido a la sugerencia, tienen diferentes planes de ejecución (y la diferencia puede ser sutil, como un iterador que se ve igual en ambos planes, pero
ordered: true
solo en uno; o un número muy diferente de filas estimadas porque una se compiló antes de un cambio de datos importante). También podría ser que se esté tomando un escaneo de orden de asignación, como James describió correctamente en su respuesta.En cualquier caso, dado que está ejecutando una consulta sin
ORDER BY
, SQL Server infiere que no le importa el orden, por lo que se apaga y determina la forma más eficiente de devolver las filas (no le importa el orden si no )Déjame hacer esto muy claro:
Si desea o espera un cierto orden, agregue una cláusula ORDER BY
Esto ha llegado antes:
Y he blogueado al respecto:
Aquí hay una cita de este último que reitera lo que dije para abordar su comentario sobre el uso de una pista de índice en lugar de una
ORDER BY
cláusula:Conor Cunningham, un tipo bastante inteligente, directamente responsable de gran parte de lo que hace SQL Server cuando procesa una consulta por usted, también ha publicado un blog al respecto aquí:
Lea un poco y luego agregue una
ORDER BY
cláusula a sus consultas antes de quejarse de una ordenación diferente o inesperada.fuente