目前有一个像;
这样的索引 CREATE UNIQUE NONCLUSTERED INDEX [CDPAYAPP_INDEX03] ON [dbo].[CDPAYAPP]
(
[CLSVC_ID] ASC,
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
不幸的是,在我们的一些客户端,CLSVC_ID的值对于100万行或更多行中的100k或更多行可以为零。此基数似乎会导致优化器偶尔将索引视为低于最佳值,从而导致表扫描。每天多次更新统计数据可能会有所帮助,但并非总是如此。
我尝试应用FILTERING INDEX子句,例如;
create UNIQUE NONCLUSTERED index CDPAYAPP_INDEX3A ON CDPAYAPP (CLSVC_ID, ID)
WHERE CLSVC_ID > 0;
但是注意到如果我请求两个索引列之外的任何列,它使用原始索引而不是筛选索引。如果我只选择索引的列,它将使用过滤的索引。
为什么?
答案 0 :(得分:1)
[1]当使用过滤索引工作(CREATE INDEX ...以及执行DML语句时)时,我们遵循以下设置:
SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, QUOTED_IDENTIFIER, ... etc. ... ON
SET NUMERIC_ROUNDABORT OFF
来源(请参阅[过滤索引的必需SET选项]部分):https://docs.microsoft.com/en-us/sql/t-sql/statements/create-index-transact-sql
所以我会在CREATE INDEX期间使用这些SET,但也会在SELECT / I / U / D执行期间使用。
注意:ANSI {NULLS和QUOTED_IDENTIFIER应该在CREATE [PROCEDURE] ...
关键字之前的SQL模块(例如存储过程)之外以及SQL模块中的其他设置。
[2] SQL Server是否已参数化:WHERE CLSVC_ID > @p
其中@p的值是否大于0?如果是,那么我会使用以下解决方案:
WHERE CLSVC_ID > 0 -- Predicate used for filtered index
AND CLSVC_ID > @p
这样,SQL Server就会知道@p参数总是> 0