2017-06-06 43 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