2017-06-06 77 views
2

目前有一个像索引;SQL Server过滤索引性能

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值可以是零100K或多行了几百万总行。这种基数似乎会导致优化器偶尔会将索引视为低于最佳值,从而导致表扫描。一天多次更新统计信息可以帮助但不总是。

我试图应用FILTERING INDEX子句,如;

create UNIQUE NONCLUSTERED index CDPAYAPP_INDEX3A ON CDPAYAPP (CLSVC_ID, ID) 
WHERE CLSVC_ID > 0; 

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

为什么?

+0

,你能不能给我们查询,其查询计划优化? https://www.brentozar.com/pastetheplan/ – Hybris95

回答

1

[1]工作时(CREATE INDEX ...以及当DML语句执行)与过滤指标,我们遵循以下设置:

SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, QUOTED_IDENTIFIER, ... etc. ... ON 
SET NUMERIC_ROUNDABORT OFF 

源(见[需要设置选项筛选索引]):https://docs.microsoft.com/en-us/sql/t-sql/statements/create-index-transact-sql

所以我会在CREATE INDEX期间使用这些设置,但在SELECT/I/U/D执行期间也是如此。 注意:在CREATE [PROCEDURE] ...关键字和SQL模块中的其他设置之前,ANSI_NULLS和QUOTED_IDENTIFIER应该在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