Tôi đã có thể repro trên 2008 R1 SP3 10:00.5512 nhưng cài đặt CU (14) mới nhất đã sửa nó.
Xem xét các lỗi đã được sửa trong các phiên bản can thiệp, có vẻ như bạn cần nâng cấp lên bản dựng bao gồm sửa lỗi sau.
Vi phạm quyền truy cập khi bạn chạy truy vấn chứa nhiều giá trị không đổi trong mệnh đề IN trong SQL Server 2008 hoặc SQL Server 2012
Như bạn đang ở trên 2008 R2, bạn sẽ cần ít nhất CU 9 cho SP1 hoặc CU 5 cho SP2.
Mô tả các triệu chứng hơi ngắn gọn nhưng đề cập đến các kiểu dữ liệu không khớp
Khi bạn chạy truy vấn có chứa nhiều giá trị không đổi trong mệnh đề IN trong Microsoft SQL Server 2008, Microsoft SQL Server 2012 hoặc Microsoft SQL Server 2008 R2, có thể xảy ra vi phạm truy cập.
Lưu ý Đối với sự cố xảy ra, các hằng số trong mệnh đề IN không thể khớp chính xác với kiểu dữ liệu cột.
Nó không định nghĩa "nhiều". Từ thử nghiệm tôi đã nghi ngờ điều này có thể có nghĩa là "20 hoặc nhiều hơn" vì đây dường như là điểm cắt giữa hai phương pháp ước lượng khác nhau.
Sự cố đã xảy ra bên trong một vài phương thức được gọi bằng CScaOp_In::FCalcSelectivity()
các tên như LoadHistogramFromXVariantArray()
và CInMemHistogram::FJoin() -> WalkHistograms()
.
Đối với 19 hoặc ít hơn sự khác biệt trong các mục danh sách, các phương thức này hoàn toàn không được gọi. Một lỗi SQL Sever 2000 tương tự cũng đề cập đến điểm bị cắt này là đáng kể.
Tạo một bảng thử nghiệm với 100.000 hàng dữ liệu thử nghiệm ngẫu nhiên có giá trị từ 0 đến 1047 và biểu đồ bắt đầu như sau
+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0 | 0 | 104 | 0 | 1 |
| 8 | 672 | 118 | 7 | 96 |
| 13 | 350 | 118 | 4 | 87.5 |
| 18 | 395 | 107 | 4 | 98.75 |
| 23 | 384 | 86 | 4 | 96 |
| 28 | 371 | 85 | 4 | 92.75 |
+--------------+------------+---------+---------------------+----------------+
Truy vấn
SELECT * FROM dbo.[TestTable]
where mpnr in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)
option (maxdop 1)
Hiển thị các hàng ước tính của năm 1856.
Đây chính xác là những gì sẽ được mong đợi bằng cách lấy các hàng ước tính cho 19 vị từ đẳng thức riêng lẻ và thêm chúng lại với nhau.
+-------+----------------+-------+
| 1-7 | AVG_RANGE_ROWS | 96 |
| 8 | EQ_ROWS | 118 |
| 9-12 | AVG_RANGE_ROWS | 87.5 |
| 13 | EQ_ROWS | 118 |
| 14-17 | AVG_RANGE_ROWS | 98.75 |
| 18 | EQ_ROWS | 107 |
| 19 | AVG_RANGE_ROWS | 96 |
+-------+----------------+-------+
7*96 + 118 + 4*87.5 + 118 + 4*98.75 + 107 + 1*96 = 1856
Công thức không còn hoạt động sau khi 20
được thêm vào danh sách (Các hàng ước tính 1902.75
thay vì 1952
thêm một hàng khác 96
vào tổng số sẽ tạo ra).
BETWEEN
dường như sử dụng một phương pháp khác để tính toán ước tính cardinality.
where mpnr BETWEEN 1 AND 20
ước tính chỉ có 1829,6 hàng. Tôi không biết làm thế nào mà nó được bắt nguồn từ biểu đồ được hiển thị.