Chcę mieć szybkie wyszukiwanie w oparciu o to, czy dwie kolumny są równe. Próbowałem użyć kolumny obliczeniowej z indeksem, ale wydaje się, że SQL Server go nie używa. Jeśli po prostu użyję statycznie wypełnionej kolumny bitów z indeksem, otrzymam oczekiwane wyszukiwanie indeksu.
Wydaje się, że istnieją jeszcze takie pytania, ale żadne z nich nie koncentruje się na tym, dlaczego indeks nie byłby używany.
Tabela testowa:
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)
I zapytanie:
select Id from Diffs where DiffPersisted = 1
select Id from Diffs where DiffComp = 1
select Id from Diffs where DiffStatic = 1
źródło
COALESCE
na to, że w tym momencie możesz się po prostu pozbyć ; Wydaje mi się, żeCASE
instrukcja już zwróciła0
lub1
, aleISNULL
była obecna tylko po to, aby SQL Server zwrócił wartość zerowąBIT
dla kolumny obliczanej. JednakCOALESCE
nadal da kolumnę zerowalną. Więc jedynym skutkiem tej zmiany, z lub bezCOALESCE
, jest to, że kolumna obliczeniowa jest teraz zerowa, ale można użyć wyszukiwania indeksu.COALESCE
? Dlaczego miałbym to zatrzymać?COALESCE
. Starałem się zachować wygląd i intencję twojego oryginalnego kodu i nie testowałem bez niego, więc testowanie będzie na tobie. (Nie umiem też wyjaśnić, dlaczegoISNULL
tam byłeś ).Jest to specyficzne ograniczenie obliczonej przez SQL Server logiki dopasowywania kolumn, gdy
ISNULL
używany jest element zewnętrzny , a typem danych kolumny jestbit
.Zgłoszenie błędu
Aby uniknąć tego problemu, można zastosować jedno z następujących obejść:
ISNULL
(jedyny sposób na utworzenie kolumny obliczeniowejNOT NULL
).bit
typu danych jako końcowego typu kolumny obliczanej.PERSISTED
i włącz flagę śledzenia 174 .Detale
Sedno problemu polega na tym, że bez flagi śledzenia 174 wszystkie obliczone odwołania do kolumn w zapytaniu (nawet utrwalone) są zawsze rozszerzane do definicji podstawowej na bardzo wczesnym etapie kompilacji zapytania.
Idea rozszerzenia polega na tym, że może on umożliwiać uproszczenia i przepisywanie, które mogą działać tylko na definicji, a nie na samej nazwie kolumny. Na przykład mogą istnieć predykaty w zapytaniu odnoszące się do tej kolumny obliczeniowej, które mogłyby uczynić część obliczeń zbędną lub w inny sposób bardziej ograniczoną.
Po rozważeniu wczesnych uproszczeń i ponownych zapisów, kompilacja zapytania próbuje dopasować wyrażenia w zapytaniu do kolumn obliczonych (wszystkie kolumny obliczone, nie tylko te pierwotnie znalezione w tekście zapytania).
Niezmienione obliczone wyrażenia kolumnowe dopasowują się z powrotem do oryginalnej kolumny obliczeniowej bez problemu w większości przypadków. Wygląda na to, że występuje błąd związany z dopasowaniem wyrażenia
bit
typu do skrajnegoISNULL
. Dopasowywanie kończy się niepowodzeniem w tym konkretnym przypadku, nawet jeśli szczegółowe badanie elementów wewnętrznych wykazuje, że powinno się to udać.źródło