Sql-Server
篩選條件未正確應用於聚集列儲存索引
使用下面的範例,謂詞是相同的,但是頂部語句(正確)返回 0 行,底部語句返回 1 - 即使謂詞不匹配:
declare @barcode nchar(22)=N'RECB012ZUKI449M1VBJZ' declare @tableId int = null declare @total decimal(10, 2) = 5.17 SELECT 1 FROM [dbo].[transaction] WITH (INDEX([IX_Transaction_TransactionID_PaymentStatus_DeviceID_DateTime_All])) WHERE Barcode = @barcode AND StatusID = 1 AND TableID = @tableID AND @total <= Total SELECT 1 FROM [dbo].[transaction] WHERE Barcode = @barcode AND StatusID = 1 AND TableID = @tableID AND @total <= Total
為什麼會發生這種情況?
更多資訊:
- 頂部語句中的非聚集索引未過濾
- CheckDB 返回 0 個問題
- 伺服器版本:
Microsoft SQL Azure (RTM) - 12.0.2000.8 Dec 19 2018 08:43:17 Copyright (C) 2018 Microsoft Corporation
粘貼計劃連結:
https://www.brentozar.com/pastetheplan/?id=S1w_rU68E
更多資訊:
已執行
dbcc checktable ([transaction]) with all_errormsgs, extended_logical_checks, data_purity
表明沒有問題。還原此數據庫的備份時,我可以可靠地針對此表重現該問題。
此錯誤不需要刪除或重命名列。
您還將看到
statusId = 100
在任何版本的列中從未出現過的相同行為。要求
集群列儲存
非聚集 b 樹索引
在列儲存上執行查找的計劃
- 增量儲存中的目標行
- 推送的非 SARG 謂詞
- 使用相等測試與 NULL 進行比較
例子
DROP TABLE IF EXISTS dbo.Example; GO CREATE TABLE dbo.Example ( c1 integer NOT NULL, c2 integer NULL, INDEX CCS CLUSTERED COLUMNSTORE, INDEX IX NONCLUSTERED (c1) ); GO INSERT dbo.Example (c1, c2) VALUES (1, NULL); GO DECLARE @c2 integer = NULL; -- Returns one row but should not SELECT E.* FROM dbo.Example AS E WITH (INDEX(IX)) WHERE E.c2 = @c2;
以下任何一項都將避免該錯誤:
- 使用任何方法將行移出增量儲存,包括使用指定的 compress rowgroups 選項進行重組
- 編寫謂詞以明確拒絕
= NULL
- 啟用未記錄的跟踪標誌 9130 以避免將謂詞推送到查找中
db<>小提琴展示。
此錯誤已在 SQL Server 2017 的 CU15(和 SQL Server 2016 SP2 的 CU7)中修復**:**
修復:對具有聚集列儲存索引和非聚集行儲存索引的表進行查詢可能會在 SQL Server 2016 和 2017 中返回不正確的結果