Por que o SQL Server não garante a classificação dos resultados sem ORDER BY

Olá de novo. Em junho, a OTUS lança novamente o curso “MS SQL Server Developer” , tradicionalmente na véspera do início do curso, começamos a compartilhar material sobre o assunto com você.




Se sua consulta não contiver ORDER BY, não será possível garantir que a classificação dos resultados não seja alterada ao longo do tempo.

Obviamente, no começo tudo será bastante previsível, mas à medida que ocorrerem alterações (em índices, tabelas, configuração do servidor, quantidade de dados), você poderá encontrar algumas surpresas desagradáveis.

Vamos começar com algo simples: faça um SELECT para a tabela Users do banco de dados Stack Overflow. Esta tabela possui um índice de cluster para a coluna Id, que começa em um e aumenta para um trilhão. Para esta consulta, os dados são retornados na ordem do índice em cluster:



Mas se você criar um índice em DisplayName e Location, o SQL Server decidirá repentinamente usar um novo índice, não um cluster:



Aqui está o plano de execução:



Por que o SQL Server decidiu usar esse índice, embora não precise ser classificado por DisplayName e local? Porque esse índice é a menor cópia dos dados que precisam ser obtidos. Vejamos o tamanho dos índices com sp_BlitzIndex:



O índice clusterizado (CX / PK) possui cerca de 8,9 milhões de linhas e seu tamanho é de 1,1 GB .

No índice não agrupado para DisplayName, o Location também possui cerca de 8,9 milhões de linhas, mas seu tamanho é de apenas 368 MB . Se você precisar fazer uma varredura para obter os resultados da consulta, por que não escolher a menor fonte de dados, pois será mais rápida. É por esse motivo que o SQL Server fez isso.

"Sim, mas meu pedido contém ONDE".


Ok, agora que temos um índice para DisplayName e Location, vamos tentar uma consulta que procure por um nome específico (DisplayName). Os resultados são classificados por DisplayName:



O plano de execução mostra que o índice é usado por DisplayName e Location:



Mas se você observar um valor diferente, os resultados não serão mais classificados por DisplayName: o



SQL Server descobriu que Alex tem muito mais razoável para executar o Clustered Index Digitalizar em vez de pesquisa de índice + pesquisa de chave:



mesmo nesses casos realmente simples, você não pode garantir que o SQL Server sempre use a cópia dos dados que você espera.

Recentemente, deparei-me com casos muito mais complicados:

  • Removendo o índice usado na consulta
  • (Forced Parameterization), , SQL Server
  • (Compatibility Level) (Cardinality Estimator), .



.



All Articles