简体   繁体   中英

SQL Server filtered index with multiple columns in where clause

I have a scenario where a filtered index is to be created on a table say Table1 with columns A, B, C . The condition when the index has to be applied is if any one of the columns has a value (ie not null).

Index should not be applicable if all the columns are null.

OR does not work, IN cannot be used. So I am stuck. Can anyone please help with suggestions?

CREATE UNIQUE INDEX UIX_Table1
ON Table1 (A,B,C)
WHERE A IS NOT NULL OR B IS NOT NULL OR C IS NOT NULL

You have to create separate NOT NULL filtered index and your query will use them.

CAVEAT : As this indexes are separate, you cannot have the unique index on the combination of them.

CREATE TABLE TestFilter(ColumnA int null,ColumnB int null,ColumnC int null)

CREATE INDEX IX_Filtered_ColumnA ON TestFilter(columnA,ColumnB,ColumnC) 
where ColumnA IS NOT NULL

CREATE INDEX IX_Filtered_ColumnB ON TestFilter(columnA,ColumnB,ColumnC) 
where ColumnB IS NOT NULL

CREATE INDEX IX_Filtered_ColumnC ON TestFilter(columnA,ColumnB,ColumnC) 
where ColumnC IS NOT NULL

Ideally, your query should use the above indexes. You can try with your query and see if the index is getting leveraged.

select *
from TestFilter
where ColumnA is not null or ColumnB is not null or ColumnC is not null

Filtered indexes are limited , you can not use or as part of your filtration

Limitations and Restrictions

  • You cannot create a filtered index on a view. However, the query optimizer can benefit from a filtered index defined on a table that is referenced in a view. The query optimizer considers a filtered index for a query that selects from a view if the query results will be correct.
  • You cannot create a filtered index on a table when the column accessed in the filter expression is of a CLR data type.
  • Filtered indexes are defined on one table and only support simple comparison operators. If you need a filter expression that references multiple tables or has complex logic, you should create a view. Filtered indexes do not support LIKE operators.
  • A column in the filtered index expression does not need to be a key or included column in the filtered index definition if the filtered index expression is equivalent to the query predicate and the query does not return the column in the filtered index expression with the query results.
  • A column in the filtered index expression should be a key or included column in the filtered index definition if the query predicate uses the column in a comparison that is not equivalent to the filtered index expression.
  • A column in the filtered index expression should be a key or included column in the filtered index definition if the column is in the query result set.
  • The clustered index key of the table does not need to be a key or included column in the filtered index definition. The clustered index key is automatically included in all nonclustered indexes, including filtered indexes.
  • If the comparison operator specified in the filtered index expression of the filtered index results in an implicit or explicit data conversion, an error will occur if the conversion occurs on the left side of a comparison operator. A solution is to write the filtered index expression with the data conversion operator (CAST or CONVERT) on the right side of the comparison operator.
  • Review the required SET options for filtered index creation in CREATE INDEX (Transact-SQL) syntax

Reference

as it has been mention in bullet no. 3 , you can make a view and combine those 3 columns into one and make a filtered index on that column from view.

Instead of a filtered index , which has many limitations, you can use an indexed view with the same filters

CREATE VIEW vwTable1Filtered
AS
SELECT A, B, C
FROM Table1
WHERE A IS NOT NULL OR B IS NOT NULL OR C IS NOT NULL;

GO

CREATE UNIQUE CLUSTERED INDEX vwTable1Filtered_UIX
  ON vwTable1Filtered(A, B, C);

GO

Using view matching should mean that this index will normally be used. However, specifying the view explicitly with a NOEXPAND hint may prove more reliable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM