Вычисленный индекс столбца не используется

Я хочу иметь быстрый поиск, основанный на том, если два столбца равны. Я попытался использовать вычисляемый столбец с индексом, но 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

И итоговые планы выполнения: «План

12 голосов | спросил David Faivre 16 WedEurope/Moscow2015-12-16T22:10:18+03:00Europe/Moscow12bEurope/MoscowWed, 16 Dec 2015 22:10:18 +0300 2015, 22:10:18

1 ответ


4

Это конкретное ограничение логики сопоставления вычисляемых столбцов SQL Server, когда используется внешний код ISNULL, а тип данных столбец bit.

Отчет об ошибке

Чтобы избежать этой проблемы, можно использовать любые из следующих обходных решений:

  1. Не используйте внешний код ISNULL (единственный способ сделать вычисленный столбец NOT NULL) литий>
  2. Не используйте тип данных bit в качестве конечного типа вычисленного столбца.
  3. Сделать вычисленный столбец PERSISTED и включить флаг трассировки 174 .

Подробнее

Сердцем проблемы является то, что без флага 174 отрисовки все вычисленные значения столбцов в запросе (даже сохраняются) всегда очень быстро расширяются в базовое определение в начале компиляции запросов.

Идея расширения заключается в том, что он может включать упрощения и перезаписи, которые могут работать только над определением, а не только от имени столбца. Например, могут быть предикаты в запросе, ссылающиеся на вычисляемый столбец, который может сделать часть избыточности вычислений или иным образом более ограниченным.

Как только ранние упрощения и перезаписи рассматриваются, компиляция запросов пытается сопоставить выражения в запросе с вычисленными столбцами (все вычисленные столбцы, а не только те, которые первоначально были найдены в тексте запроса).

Неизмененные вычисленные выражения столбцов в большинстве случаев совпадают с исходным вычисленным столбцом. Кажется, что ошибка связана с выражением типа bit с внешним кодом ISNULL. Согласование неудачно в этом конкретном случае, даже если подробное исследование внутренних компонентов показывает, что оно должно быть успешным.

ответил Paul White 18 MarpmSun, 18 Mar 2018 14:46:25 +03002018-03-18T14:46:25+03:0002 2018, 14:46:25

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132