Como indexar para consultas de desigualdade?

10

Eu tenho uma consulta que está excluindo dados com base no valor de uma coluna flutuante

select * 
from My_Table
where my_Float_column != 0 and my_Float_column is not null

Não quero indexar um tipo de flutuação se puder ajudar. O plano de execução seria inteligente o suficiente para usar um índice filtrado como o abaixo (onde estou indexando apenas os valores 0 e nulo) para aumentar o desempenho?

CREATE NONCLUSTERED INDEX IX_My_Table_Float_Filtered
    ON My_Table (my_Float_column)
    WHERE my_Float_column = 0 or my_Float_column is null
Neil P
fonte

Respostas:

11

O plano de execução seria inteligente o suficiente para usar um índice filtrado como o abaixo (onde estou indexando apenas os valores 0 e nulo) para aumentar o desempenho?

Não. Não há suporte direto no SQL Server para o tipo de rejeição de linha de operador único que você parece ter em mente.

Falando de maneira mais geral, o índice filtrado não é diretamente útil para a consulta especificada e não é uma definição válida de filtro de índice. Você pode criar uma exibição indexada contendo esses predicados, mas ainda assim não seria útil como maneira de localizar linhas para a consulta de destino. Você pode reescrever a consulta para usar a exibição indexada para excluir linhas buscadas com uma verificação completa separada, mas é difícil ver como isso seria uma boa ideia em geral.

O mais próximo que você poderia chegar seria provavelmente uma varredura da exibição indexada preenchendo um filtro de bitmap, com esse filtro aplicado como parte de uma varredura completa da tabela de destino. Pode ser um desafio obter a forma do plano de consulta de forma confiável.

Você também pode usar uma coluna computada persistente indexada usando uma CASEexpressão, mas novamente isso exigiria reescrever a consulta original e exigiria armazenamento para todas as linhas da tabela, além do índice.

A partir das informações fornecidas, parece que o melhor que você pode fazer é definir o índice como:

CREATE NONCLUSTERED INDEX IX_dbo_My_Table__Float_Filtered
ON dbo.My_Table (my_Float_column)
WHERE 
    my_Float_column <> 0 
    AND my_Float_column IS NOT NULL;
Paul White 9
fonte