Estou tentando analisar as consultas nesta tabela:
CREATE TABLE [dbo].[Values](
[tid] [smallint] NOT NULL,
[t] [datetime2](3) NOT NULL,
[v] [real] NOT NULL,
CONSTRAINT [PK_Values_Unique] PRIMARY KEY CLUSTERED
(
[t] ASC,
[tid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Estou revisando alguns planos de execução estimados usando o SQL Server Management Studio , primeira consulta .
SELECT *
FROM [dbo].[Values]
WHERE [tid] = 1
A exibição do plano de execução estimado para esta consulta gera:
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[Values] ([tid])
INCLUDE ([timestamp],[v])
Que, eu posso entender, quer dar uma olhada rápida por tid
, embora eu não saiba exatamente por que isso INCLUDE
é sugerido.
Então eu tentei uma segunda consulta (outro tid), que é praticamente o mesmo com outro tid
:
SELECT *
FROM [dbo].[Values]
WHERE [tid] = 1 or [tid] = 2
Mas agora, SSMS , não sugere o índice anterior.
Por que o SSMS sugere um INDEX para a primeira consulta, mas não para a segunda agora, embora sejam praticamente os mesmos?
Adicionar este ÍNDICE sugerido deve ser útil para ambos os tipos de consultas?
EDIT: Esta tabela tem mais de 2 * 10^9 linhas.
algum contexto
A primeira coisa a observar é que seu índice clusterizado não ajuda na pesquisa da
tid
coluna, porquet
é a coluna principal no índice.Se você inverter a ordem de
t
etid
na chave, esperaria que a dica do índice desaparecesse e a consulta fosse executada mais rapidamente sem adicionar novos índices.Resposta Específica
O motivo mais provável pelo qual o segundo plano de consulta não sugere um índice é que o novo filtro
tid
seleciona mais de 30% de todos os valores na tabela. Quando for esse o caso, o SQL Server geralmente preferirá a varredura da tabela em vez de buscar o índice (porque essa é a melhor estratégia). Portanto, sugerir um índice não é mais a coisa certa a fazer. Selecionar dois valores em vez de um pode ser exatamente o ponto de inflexão dessa constante de 30% no otimizadorPara explorar esse efeito, você pode forçar o retorno da dica de índice fazendo o seguinte:
.. Mas, por favor, não faça isso na produção, apenas para explorar os efeitos.
Por que incluir?
O include está aí porque se não estivesse, a execução teria que fazer assim:
tid
v
et
O INCLUDE garante que todas as colunas estejam contidas no índice, portanto, a segunda etapa não é necessária. Aliás, esta é uma das razões pelas quais você deve evitar SELECT *.