Ini adalah bug dengan SQL Server. Jika sebuah kolom dihapus dari tabel dengan indeks kolomstore berkerumun, dan kemudian kolom baru ditambahkan dengan nama yang sama, itu tampaknya menggunakan kolom lama, dihapus untuk predikat. Inilah MVCE:
Script ini dimulai dengan 10000
baris dengan statusId
dari 1
dan statusId2
dari 5
- kemudian turun statusID
kolom dan ganti nama statusId2
menjadi statusId
. Jadi pada akhirnya semua baris harus memiliki statusId
5.
Tetapi kueri berikut mengenai indeks yang tidak berkerumun ...
select *
from example
where statusId = 1
and total <= @filter
and barcode = @barcode
and id2 = @id2
... dan mengembalikan 2
baris (dengan yang dipilih statusId
berbeda dari yang tersirat oleh WHERE
klausa) ...
+-------+---------+------+-------+----------+
| id | barcode | id2 | total | statusId |
+-------+---------+------+-------+----------+
| 5 | 5 | NULL | 5.00 | 5 |
| 10005 | 5 | NULL | 5.00 | 5 |
+-------+---------+------+-------+----------+
... sedangkan yang ini mengakses toko kolom dan kembali dengan benar 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;
Saya juga telah mengangkat masalah pada portal umpan balik Azure :
Dan bagi siapa pun yang menjumpai ini, membangun kembali Clustered Columnstore Index memperbaiki masalah:
alter index cci_example on example rebuild
Membangun kembali CCI hanya memperbaiki data yang ada. Jika catatan baru ditambahkan, masalah muncul lagi pada catatan ini; jadi saat ini satu-satunya perbaikan yang diketahui untuk tabel adalah membuat ulang seluruhnya.