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

¿Cómo ordena el servidor sql sus datos?

Aunque es bueno preguntarse cómo podría explicarse que a menudo vea 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 del motor de base de datos subyacente. En otras palabras, es bueno saber por qué, pero nunca debes confiar en ello. Para MS SQL, lo único que entrega las filas de manera confiable en un cierto orden es un ORDER BY explícito cláusula.

Los diferentes RDMBS-es no solo se comportan de manera diferente, sino que una instancia en 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 "caliente" 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 previa sobre la implementación (p. ej.:"hay un índice agrupado, por lo que es probable que los datos se devuelvan por orden del índice agrupado"), siempre existe la posibilidad de que haya otro mecanismo que no No sé, eso hace que las filas se devuelvan en un orden diferente (ej. 1:"si otra sesión acaba de hacer un escaneo completo de la tabla con un ORDER BY explícito el conjunto de resultados puede haber sido almacenado en caché; un análisis completo posterior intentará devolver las filas de la memoria caché"; ex2:"un GROUP BY puede implementarse clasificando los datos, lo que afecta el orden en que se devuelven las filas"; ej. 3:"Si las columnas seleccionadas están todas en un índice secundario que ya está almacenado en caché 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, inicie el servidor SQL (estoy usando 2008). Crea esta tabla:

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

Examine la tabla y compruebe que se creó un índice agrupado para admitir la primary key en el id columna. Por ejemplo, en sql server management studio, puede usar la vista de árbol y navegar a la carpeta de índices debajo de su tabla. Allí 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()

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

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

Ahora debería tener 65536 filas:

select COUNT(*) 
from   test_order

Ahora, seleccione todas las filas sin utilizar un orden por:

select *
from   test_order

Lo más probable es que los resultados se devuelvan por orden de la clave principal (aunque no hay garantía). Aquí está el resultado que obtuve (que de hecho es 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 sino la posición ordinal de la fila en el resultado)

Ahora, cree un índice secundario en el name columna:

create index idx_name on test_order(name)

Seleccione todas las filas, pero recupere solo el name columna:

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 solo escaneando el índice (i.o.w. idx_name es una cobertura índice). Aquí está el resultado que obtuve, que de hecho es por orden de name .

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

Ahora, seleccione todas las columnas y todas las filas nuevamente:

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 puede ver, bastante diferente de la primera vez que ejecutamos 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 de por qué se puede observar un orden en particular, pero incluso entonces no siempre puede predecirlo (como en el último caso) sin tener un conocimiento íntimo de la implementación y el estado del tiempo de ejecución.