Как индексировать запросы на неравенство?

10

У меня есть запрос, который исключает данные, основанные на значении столбца с плавающей точкой

select * 
from My_Table
where my_Float_column != 0 and my_Float_column is not null

Я не хочу индексировать тип с плавающей точкой, если смогу помочь. Будет ли план выполнения достаточно умным, чтобы использовать отфильтрованный индекс, подобный приведенному ниже (где я индексирую только нулевые и нулевые значения), чтобы повысить производительность?

CREATE NONCLUSTERED INDEX IX_My_Table_Float_Filtered
    ON My_Table (my_Float_column)
    WHERE my_Float_column = 0 or my_Float_column is null
Нил П
источник

Ответы:

11

Будет ли план выполнения достаточно умным, чтобы использовать отфильтрованный индекс, подобный приведенному ниже (где я индексирую только нулевые и нулевые значения), чтобы повысить производительность?

Нет. В SQL Server нет прямой поддержки такого рода отклонения строк одним оператором, которое вы, вероятно, имеете в виду.

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

Самое близкое, что вы могли бы получить, это, вероятно, сканирование индексированного представления, заполняющего фильтр растровых изображений, с этим фильтром, применяемым как часть полного сканирования целевой таблицы. Может быть сложно получить эту форму плана запроса надежно.

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

Судя по приведенной информации, лучше всего определить индекс следующим образом:

CREATE NONCLUSTERED INDEX IX_dbo_My_Table__Float_Filtered
ON dbo.My_Table (my_Float_column)
WHERE 
    my_Float_column <> 0 
    AND my_Float_column IS NOT NULL;
Пол Уайт 9
источник