Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como o sql server classifica seus dados?


Embora seja bom se perguntar como pode ser explicado que você costuma ver a mesma ordem, gostaria de salientar que nunca é uma boa ideia confiar na ordem implícita causada pela implementação específica do mecanismo de banco de dados subjacente. Em outras palavras, é bom saber o porquê, mas você nunca deve confiar nisso. Para MS SQL, a única coisa que entrega as linhas de forma confiável em uma determinada ordem é um ORDER BY explícito cláusula.

Não apenas diferentes RDMBS-es se comportam de maneira diferente, como uma instância específica pode se comportar de maneira diferente devido a uma atualização (patch). Além disso, até mesmo o estado do software RDBMS pode ter um impacto:um banco de dados "quente" se comporta de maneira diferente de um "frio", uma pequena tabela se comporta de maneira diferente de uma grande.

Mesmo que você tenha informações básicas sobre a implementação (ex:"existe um índice clusterizado, portanto, é provável que os dados sejam retornados por ordem do índice clusterizado"), há sempre a possibilidade de haver outro mecanismo que você não não sei disso faz com que as linhas sejam retornadas em uma ordem diferente (ex1:"se outra sessão acabou de fazer uma varredura completa da tabela com um ORDER BY explícito o conjunto de resultados pode ter sido armazenado em cache; uma varredura completa subsequente tentará retornar as linhas do cache"; ex2:"a GROUP BY pode ser implementado ordenando os dados, impactando assim na ordem em que as linhas são retornadas"; ex3:"Se as colunas selecionadas estiverem todas em um índice secundário que já está armazenado em cache na memória, o mecanismo pode verificar o índice secundário em vez da tabela, provavelmente retornando as linhas por ordem do índice secundário").

Aqui está um teste muito simples que ilustra alguns dos meus pontos.

Primeiro, inicialize o servidor SQL (estou usando o 2008). Crie esta tabela:
create table test_order (
    id int not null identity(1,1) primary key
,   name varchar(10) not null 
)

Examine a tabela e testemunhe que um índice agrupado foi criado para dar suporte à primary key no id coluna. Por exemplo, no sql server management studio, você pode usar a visualização em árvore e navegar até a pasta de índices abaixo de sua tabela. Lá você deve ver um índice, com um nome como:PK__test_ord__3213E83F03317E3D (Clustered)

Insira a primeira linha com esta instrução:
insert into test_order(name)
select RAND()

Insira mais linhas repetindo esta instrução 16 vezes:
insert into test_order(name)
select RAND()
from   test_order

Agora você deve ter 65536 linhas:
select COUNT(*) 
from   test_order

Agora, selecione todas as linhas sem usar uma ordem por:
select *
from   test_order

Muito provavelmente, os resultados serão retornados por ordem da chave primária (embora não haja garantia). Aqui está o resultado que obtive (que é de fato por ordem de chave primária):
#      id    name
1      1     0.605831
2      2     0.517251
3      3     0.52326
.      .     .......
65536  65536 0.902214

(o # não é uma coluna, mas a posição ordinal da linha no resultado)

Agora, crie um índice secundário no name coluna:
create index idx_name on test_order(name)

Selecione todas as linhas, mas recupere apenas o name coluna:
select name
from   test_order

Muito provavelmente os resultados serão retornados por ordem do índice secundário idx_name, pois a consulta pode ser resolvida apenas verificando o índice (i.o.w. idx_name é uma cobertura índice). Aqui está o resultado que obtive, que é de fato por ordem de name .
#      name
1      0.0185732
2      0.0185732
.      .........
65536  0.981894

Agora, selecione todas as colunas e todas as linhas novamente:
select * 
from test_order

Segue o resultado que obtive:
#      id    name
1      17    0.0185732
2      18    0.0185732
3      19    0.0185732
...    ..    .........

como você pode ver, bem diferente da primeira vez que executamos essa consulta. (Parece que as linhas são ordenadas pelo índice secundário, mas não tenho uma explicação para isso).

De qualquer forma, a linha inferior é - não confie na ordem implícita. Você pode pensar em explicações de por que uma ordem específica pode ser observada, mas mesmo assim nem sempre pode prever (como no último caso) sem ter um conhecimento profundo da implementação e do estado de tempo de execução.