Đây là một lỗi với SQL Server. Nếu một cột bị xóa khỏi một bảng có chỉ mục cửa hàng cột được phân cụm, và sau đó một cột mới được thêm cùng tên, thì nó dường như đang sử dụng cột cũ, bị xóa cho vị ngữ. Đây là MVCE:
Kịch bản này bắt đầu với 10000
hàng với statusId
của 1
và statusId2
của 5
- sau đó giảm các statusID
cột và đặt lại tên statusId2
để statusId
. Vì vậy, ở cuối tất cả các hàng nên có statusId
5.
Nhưng truy vấn sau đây đánh vào chỉ mục không được nhóm ...
select *
from example
where statusId = 1
and total <= @filter
and barcode = @barcode
and id2 = @id2
... và trả về 2
các hàng (với lựa chọn statusId
khác với ngụ ý của WHERE
mệnh đề) ...
+-------+---------+------+-------+----------+
| id | barcode | id2 | total | statusId |
+-------+---------+------+-------+----------+
| 5 | 5 | NULL | 5.00 | 5 |
| 10005 | 5 | NULL | 5.00 | 5 |
+-------+---------+------+-------+----------+
... trong khi cái này truy cập vào kho cột và trả về đúng 0
select count(*)
from example
where statusId = 1
MVCE
/*Create table with clustered columnstore and non clustered rowstore*/
CREATE TABLE example
(
id INT IDENTITY(1, 1),
barcode CHAR(22),
id2 INT,
total DECIMAL(10,2),
statusId TINYINT,
statusId2 TINYINT,
INDEX cci_example CLUSTERED COLUMNSTORE,
INDEX ix_example (barcode, total)
);
/* Insert 10000 rows all with (statusId,statusId2) = (1,5) */
INSERT example
(barcode,
id2,
total,
statusId,
statusId2)
SELECT TOP (10000) barcode = row_number() OVER (ORDER BY @@spid),
id2 = NULL,
total = row_number() OVER (ORDER BY @@spid),
statusId = 1,
statusId2 = 5
FROM sys.all_columns c1, sys.all_columns c2;
ALTER TABLE example
DROP COLUMN statusid
/* Now have 10000 rows with statusId2 = 5 */
EXEC sys.sp_rename
@objname = N'dbo.example.statusId2',
@newname = 'statusId',
@objtype = 'COLUMN';
/* Now have 10000 rows with StatusID = 5 */
INSERT example
(barcode,
id2,
total,
statusId)
SELECT TOP (10000) barcode = row_number() OVER (ORDER BY @@spid),
id2 = NULL,
total = row_number() OVER (ORDER BY @@spid),
statusId = 5
FROM sys.all_columns c1, sys.all_columns c2;
/* Now have 20000 rows with StatusID = 5 */
DECLARE @filter DECIMAL = 5,
@barcode CHAR(22) = '5',
@id2 INT = NULL;
/*This returns 2 rows from the NCI*/
SELECT *
FROM example WITH (INDEX = ix_example)
WHERE statusId = 1
AND total <= @filter
AND barcode = @barcode
AND id2 = @id2;
/*This counts 0 rows from the Columnstore*/
SELECT COUNT(*)
FROM example
WHERE statusId = 1;
Tôi cũng đã nêu ra một vấn đề trên cổng thông tin phản hồi Azure :
Và đối với bất kỳ ai khác gặp phải điều này, việc xây dựng lại Indexed Clusterstore Index sẽ khắc phục vấn đề:
alter index cci_example on example rebuild
Xây dựng lại CCI chỉ sửa chữa bất kỳ dữ liệu hiện có. Nếu hồ sơ mới được thêm vào, vấn đề phát sinh lại trên các hồ sơ này; Vì vậy, hiện tại sửa chữa duy nhất được biết cho bảng là để tạo lại nó hoàn toàn.