Eu tenho uma tabela que captura a plataforma host em que um usuário está executando. A definição da tabela é simples:
IF OBJECT_ID('[Auth].[ActivityPlatform]', 'U') IS NULL
BEGIN
CREATE TABLE [Auth].[ActivityPlatform] (
[ActivityPlatformId] [tinyint] IDENTITY(1,1) NOT NULL
,[ActivityPlatformName] [varchar](32) NOT NULL
,CONSTRAINT [PK_ActivityPlatform] PRIMARY KEY CLUSTERED ([ActivityPlatformId] ASC)
,CONSTRAINT [UQ_ActivityPlatform_ActivityPlatformName] UNIQUE NONCLUSTERED ([ActivityPlatformName] ASC)
) ON [Auth];
END;
GO
Os dados que ele armazena são enumerados com base em um método JavaScript que usa informações do navegador (não sei muito mais do que isso, mas posso descobrir se necessário):
Quando eu executo um basic SELECT
sem um explicit ORDER BY
, porém, o Execution Plan mostra que está usando o UNIQUE NONCLUSTERED
índice para ordenar ao invés do CLUSTERED
índice.
SELECT * FROM [Auth].[ActivityPlatform]
Ao especificar explicitamente o ORDER BY
, ele classifica corretamente por ActivityPlatformId
.
SELECT * FROM [Auth].[ActivityPlatform] ORDER BY [ActivityPlatformId]
DBCC SHOWCONTIG('[Auth].[ActivityPlatform]') WITH ALL_LEVELS, TABLERESULTS
não mostra nenhuma fragmentação de tabela.
O que estou perdendo que poderia causar isso? Eu pensei tanto que a tabela foi criada em um índice clusterizado, ela deveria classificar automaticamente por ela implicitamente sem a necessidade de especificar ORDER BY
. Qual a preferência do SQL Server na escolha do UQ? Existe algo que eu preciso especificar na criação da tabela?
Não, a classificação não é implícita e não deve ser confiável. De fato, na primeira dica de ferramenta, você pode ver que está explicitamente declarado que
Ordered = False
. Isso significa que o SQL Server não fez nada para implementar qualquer classificação. O que você observa é apenas o que aconteceu , não o que tentou fazer.Se você quiser prever uma ordem de classificação confiável, digite o
ORDER BY
. Período. O que você pode observar quando não adicionaORDER BY
pode ser interessante, mas não pode ser confiável para se comportar de forma consistente. Na verdade, neste post, veja o nº 3, mostro como a saída de uma consulta pode mudar simplesmente por outra pessoa adicionar um índice.O
UNIQUE NONCLUSTERED
índice contém a chave de clustering, portanto, está cobrindo a consulta. Nesse caso, sua tabela tem apenas duas colunas, portanto, os índices clusterizados e não clusterizados contêm os mesmos dados (apenas classificados de maneira diferente). Ambos são do mesmo tamanho, então o otimizador pode escolher qualquer um. Que ele escolha o índice não clusterizado é um detalhe de implementação.Eu chamo isso de "coin flip".