Eu quero ter uma pesquisa rápida com base em se duas colunas são iguais. Tentei usar uma coluna computada com um índice, mas o SQL Server não parece usá-lo. Se eu apenas usar uma coluna de bits preenchida estaticamente com um índice, recebo a busca de índice esperada.
Parece que existem outras perguntas como essa, mas nenhuma se concentrou no motivo pelo qual um índice não seria usado.
Tabela de teste:
CREATE TABLE dbo.Diffs
(
Id int NOT NULL IDENTITY (1, 1),
DataA int NULL,
DataB int NULL,
DiffPersisted AS isnull(convert(bit, case when [DataA] is null and [DataB] is not null then 1 when [DataA] <> [DataB] then 1 else 0 end), 0) PERSISTED ,
DiffComp AS isnull(convert(bit, case when [DataA] is null and [DataB] is not null then 1 when [DataA] <> [DataB] then 1 else 0 end), 0),
DiffStatic bit not null,
Primary Key (Id)
)
create index ix_DiffPersisted on Diffs (DiffPersisted)
create index ix_DiffComp on Diffs (DiffComp)
create index ix_DiffStatic on Diffs (DiffStatic)
E a consulta:
select Id from Diffs where DiffPersisted = 1
select Id from Diffs where DiffComp = 1
select Id from Diffs where DiffStatic = 1
fonte
COALESCE
neste momento; Acredito que aCASE
instrução já estava garantida para retornar0
ou1
, masISNULL
estava presente apenas para que o SQL Server produzisse um valor nuloBIT
para a coluna computada. No entanto,COALESCE
ainda produzirá uma coluna anulável. Portanto, o único impacto dessa alteração, com ou sem oCOALESCE
, é que a coluna computada agora é anulável, mas a busca do índice pode ser usada.COALESCE
? Por que eu guardaria isso?COALESCE
. Tentei manter a aparência e a intenção do seu código original e não testei sem ele, para que o teste seja feito em você. (Também não sei explicar por que você o tinhaISNULL
lá.)Essa é uma limitação específica da lógica de correspondência de coluna computada do SQL Server, quando uma mais externa
ISNULL
é usada e o tipo de dados da coluna ébit
.Relatório de erro
Para evitar o problema, qualquer uma das seguintes soluções alternativas pode ser empregada:
ISNULL
(a única maneira de criar uma coluna computadaNOT NULL
).bit
tipo de dados como o tipo final da coluna computada.PERSISTED
e ative o sinalizador de rastreamento 174 .Detalhes
O cerne da questão é que, sem o sinalizador de rastreamento 174, todas as referências de coluna computadas em uma consulta (mesmo persistentes) são sempre expandidas para a definição subjacente muito cedo na compilação de consultas.
A idéia de expansão é que ela poderia permitir simplificações e reescritas que só podem funcionar na definição, não apenas no nome da coluna. Por exemplo, pode haver predicados na consulta que faz referência a essa coluna computada que pode tornar parte do cálculo redundante ou de outra forma mais restrita.
Uma vez que as simplificações e reescritas iniciais são consideradas, a compilação de consultas tenta corresponder expressões na consulta a colunas computadas (todas as colunas computadas, não apenas aquelas originalmente encontradas no texto da consulta).
As expressões da coluna computada inalterada correspondem à coluna computada original sem problemas na maioria dos casos. Parece haver um erro específico para combinar uma expressão do
bit
tipo com uma mais externaISNULL
. A correspondência não é bem-sucedida nesse caso específico, mesmo quando um exame detalhado das partes internas mostra que ela deve ser bem-sucedida.fonte