2010-01-11 18 views
10

Me preguntaba cómo servidor SQL clasifica sus datos. Observé que si tengo una tabla que no contiene la columna "Id" y selecciona datos sin "ORDER BY" el servidor sql no ordena automáticamente en la columna principal.¿Cómo clasifica el servidor SQL sus datos?

¿Alguien sabe qué regla sigue el servidor sql para ordenar sus datos?

+1

+1 buena pregunta – kevchadders

Respuesta

20

Aunque es bueno preguntarse cómo podría explicarse que a menudo veas el mismo orden, me gustaría señalar que nunca es una buena idea confiar en el orden implícito causado por la implementación particular de la base de datos subyacente. motor. En otras palabras, es bueno saber por qué, pero nunca debes confiar en ello. Para MS SQL, lo único que entrega confiablemente las filas en un cierto orden, es una cláusula ORDER BY explícita.

No solo diferentes comportamientos de RDMBS se comportan de manera diferente, una instancia particular puede comportarse de manera diferente debido a una actualización (parche). No solo eso, incluso el estado del software RDBMS puede tener un impacto: una base de datos "cálida" se comporta de manera diferente a una "fría", una tabla pequeña se comporta de manera diferente a una grande.

Incluso si tiene información de contexto sobre la implementación (por ejemplo, "hay un índice agrupado, por lo tanto, es probable que los datos se devuelvan por orden del índice agrupado"), siempre existe la posibilidad de que exista otro El mecanismo que no conoce hace que las filas se devuelvan en un orden diferente (ejemplo 1: "si otra sesión acaba de hacer una exploración de tabla completa con un ORDER BY explícito, es posible que el resultado se haya almacenado en la memoria caché; las filas del caché "; ex2:" se puede implementar un GROUP BY clasificando los datos, impactando así en el orden en que se devuelven las filas "; ex3:" Si las columnas seleccionadas están todas en un índice secundario que ya está almacenado en la memoria, el motor puede escanear el índice secundario en lugar de la tabla, lo más probable es que devuelva las filas por orden del índice secundario ").

Aquí hay una prueba muy simple que ilustra algunos de mis puntos.

Primero, arranque del servidor SQL (estoy usando 2008). Crear esta tabla:

create table test_order (
    id int not null identity(1,1) primary key 
, name varchar(10) not null 
) 

examinar la tabla y el testimonio que un índice clusted fue creado para apoyar la primary key en la columna de la id. Por ejemplo, en el estudio de administración de servidor sql, puede usar la vista en árbol y navegar a la carpeta de índices debajo de su tabla.No debería ver un índice, con un nombre como: PK__test_ord__3213E83F03317E3D (Clustered)

Inserte la primera fila con esta declaración:

insert into test_order(name) 
select RAND() 

insertar más filas repitiendo esta afirmación 16 veces:

insert into test_order(name) 
select RAND() 
from test_order 

You ahora debería tener 65536 filas:

select COUNT(*) 
from test_order 

Ahora, seleccione todas las filas sin necesidad de utilizar una orden por:

select * 
from test_order 

más probable, los resultados serán devueltos por orden de la clave principal (aunque no hay garantía). Aquí está el resultado que obtuve (que es de hecho por orden de clave principal):

#  id name 
1  1  0.605831 
2  2  0.517251 
3  3  0.52326 
.  .  ....... 
65536 65536 0.902214 

(el # no es una columna, pero la posición ordinal de las filas en el resultado)

Ahora, cree una secundaria índice en la columna name:

create index idx_name on test_order(name) 

seleccionar todas las filas, pero sólo recuperan la columna de la name:

select name 
from test_order 

Lo más probable es que los resultados se devuelvan por orden del índice secundario idx_name, ya que la consulta se puede resolver escaneando únicamente el índice (i.o.w. idx_name es un que cubre el índice). Este es el resultado que obtuve, que es de hecho por orden de name.

#  name 
1  0.0185732 
2  0.0185732 
.  ......... 
65536 0.981894 

Ahora, seleccione todas las columnas y todas las filas de nuevo:

select * 
from test_order 

Aquí está el resultado que obtuve:

#  id name 
1  17 0.0185732 
2  18 0.0185732 
3  19 0.0185732 
... .. ......... 

como se puede ver, muy diferente de la primera vez que nos encontramos esta consulta (Parece que las filas están ordenadas por el índice secundario, pero no tengo una explicación de por qué debería ser así).

De todos modos, la conclusión es - no confíe en el orden implícito. Puede pensar en explicaciones por las que se puede observar un orden en particular, pero incluso así no siempre se puede predecir (como en este último caso) sin tener un conocimiento profundo de la implementación y el estado del tiempo de ejecución.

4

Si no especifica una cláusula ORDER BY explícitamente, no hay un orden garantizado para ordenar los resultados. Ni siquiera está garantizado que se base en el índice agrupado.

Puede ver un ejemplo de esto en this article.

0

AS SQL está basado en Set thoery y Set no garantiza ningún pedido, por lo tanto, si no especifica un pedido en particular explícitamente, el pedido no estará garantizado.

0

Tuve una experiencia similar con SQL Server devolviendo resultados ordenados de forma diferente a lo esperado. Encontré que si especifica una sugerencia de tabla en la instrucción de selección, dando el nombre del índice agrupado, obtendrá los resultados ordenados como desee:

select * from test_order WITH (INDEX([ClusteredIndexName])) 
Cuestiones relacionadas