Eu estava tentando fazer alguns testes em índices filtrados ontem e criei uma situação bastante simples:
CREATE TABLE IndexTest
(
ID INT NOT NULL IDENTITY(1,1) CONSTRAINT pk_IndexTest PRIMARY KEY,
Col1 CHAR(1)
)
GO
CREATE INDEX ix_IndexTest ON IndexTest(Col1)
WHERE Col1 IS NOT NULL
GO
INSERT INTO IndexTest VALUES ('A'),('B'),('C'),('D')
INSERT INTO IndexTest VALUES (''),(''),(''),('')
INSERT INTO IndexTest VALUES (NULL),(NULL),(NULL),(NULL)
GO
Em seguida, tentei executar a seguinte consulta usando uma dica para forçá-la a usar o índice filtrado.
SELECT *
FROM IndexTest WITH (INDEX(ix_IndexTest))
GO
Mas continuo recebendo o erro:
O processador de consulta não pôde produzir um plano de consulta devido às dicas definidas nesta consulta. Reenvie a consulta sem especificar nenhuma dica e sem usar SET FORCEPLAN.
Funciona se eu remover o filtro, mas não com ele. Eu até tentei trocar o filtro de várias maneiras, como WHERE Col1 = ''
etc. Sempre que tenho um filtro, recebo esse erro. Alguém pode me dizer o porquê? Estou fazendo algo errado?
Eu tentei isso em uma instância do SQL Server 2012 e 2014 e criei um sqlfiddle dele aqui:
http://www.sqlfiddle.com/#!6/4a850/1
Edit: Não tenho certeza se isso importa, mas especificamente eu estava tentando ver se conseguia ver quais linhas estavam realmente contidas no índice. A ideia surgiu ao ver alguém usar essa técnica para recuperar dados (usando um índice não filtrado) de uma tabela corrompida.
Possivelmente, a desconexão é que o índice filtrado não filtrará automaticamente os resultados para você - você deve escrever uma cláusula WHERE que corresponda ao predicado do filtro do índice para poder usar o índice.
Em outras palavras, se você está apenas tentando obter linhas
WHERE Col1 IS NOT NULL
, ainda precisa de umaWHERE
cláusula para limitar as linhas. Se o SQL Server não puder usar o índice que você está tentando forçar a satisfazer todas as linhas a serem retornadas pela consulta, o que não pode ser feito por definição do índice que contém menos (ou o mesmo *) linhas que a tabela, ele não pode ser executado.Se você estiver tentando localizar dados do índice não clusterizado porque a tabela/CI subjacente está corrompido, provavelmente terá mais sorte com
DBCC IND/PAGE
ou com uma representação de Paul Randal empunhando um editor hexadecimal.