Eu tenho uma tabela SQL Server com cerca de 2 milhões de linhas, esta tabela armazena documentos textuais curtos. Aqui está o meu esquema:
CREATE TABLE Documents (
documentId bigint IDENTITY NOT NULL,
content nvarchar(MAX) NOT NULL,
isIndexed bit NOT NULL
)
Eu tenho um processo indexador baseado em Lucene separado que faz isso:
SELECT TOP 1 documentId, content FROM Documents WHERE isIndexed = 0
Em seguida, ele executa a operação de indexação antes de executar isto:
UPDATE Documents SET isIndexed = 1 WHERE documentId = @documentId
Inicialmente, isso funcionou bem. Quando todos os documentos na tabela não foram indexados (ou seja, todos os isIndexed
valores eram 0), cada recuperação demorava cerca de 5 ms.
No entanto, à medida que mais e mais documentos foram indexados, o tempo de recuperação aumentou lentamente. Atualmente é cerca de 150ms - uma redução de velocidade de 30 vezes. Observo que a instrução UPDATE sempre parece ser executada em menos de 2 ms, então sei que isso não é um problema.
Desde o início, a tabela sempre teve um índice não clusterizado na coluna isIndexed, mas o plano de execução real mostra que o SQL Server usa uma varredura de índice (em vez de uma busca).
O que posso fazer para acelerar o sistema?
Estou ciente de que a coluna "isIndexed" existente é ruim por si só, mas devido ao funcionamento do indexador, ele não pode solicitar documentos diretamente pelo documentId. Por esta e outras razões, não posso aceitar respostas que não resolvam o problema imediato em questão.
Um índice na coluna de bits não ajudará em nada por causa da seletividade. Você deve considerar um índice filtrado:
Você também deve incluir um
ORDER BY documentId
em seu arquivoSELECT
.Embora você deva testar isso em um ambiente de teste, porque pode ajudar,
SELECT
mas pode compensar isso com um arquivoUPDATE
.A tabela (agora) possui os seguintes índices não agrupados:
E o índice clusterizado:
Eu mudei minha consulta para isso:
para isso:
E agora as consultas são executadas em menos de 10ms novamente. O plano de execução real informa que está executando duas operações de busca de índice em IX_Indexed_ASC e IX_DocumentId_Indexed.