SQL Server筛选索引性能

时间:2017-06-06 14:12:46

标签: sql-server indexing

目前有一个像;

这样的索引
    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;

但是注意到如果我请求两个索引列之外的任何列,它使用原始索引而不是筛选索引。如果我只选择索引的列,它将使用过滤的索引。

为什么?

1 个答案:

答案 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