2つの列が等しいかどうかに基づいて高速ルックアップが必要です。インデックス付きの計算列を使用しようとしましたが、SQL Serverはそれを使用していないようです。静的に設定されたインデックス付きのビット列を使用するだけで、予想されるインデックスシークが得られます。
このような質問は他にもありますが、インデックスが使用されない理由に焦点を当てたものはありません。
テスト表:
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)
そしてクエリ:
select Id from Diffs where DiffPersisted = 1
select Id from Diffs where DiffComp = 1
select Id from Diffs where DiffStatic = 1
COALESCE
ただし、この時点で単に削除できるようです。CASE
ステートメントは、0
またはを返すことがすでに保証されていると思いますが、SQL Serverが計算列に対してnull不可を生成するためにのみ存在していると思います。ただし、null許容列は引き続き生成されます。そのため、の有無にかかわらず、この変更の1つの影響は、計算列がNULL可能になりましたが、インデックスシークを使用できることです。1
ISNULL
BIT
COALESCE
COALESCE