Ví dụ máy chủ SQL lạ gặp sự cố khi truyền sang số


20

Trong khi làm việc với C # Entity Framework, tôi nhận thấy sự cố của phiên bản SQL Server của mình.

Tôi đã có thể theo dõi nó để tuyên bố này:

SELECT * FROM dbo.[TestTable]
where mpnr in (1099059904,
1038139906,
1048119902,
1045119902,
1002109903,
1117109910,
1111149902,
1063149902,
1117159902,
1116109904,
1105079905,
1012079906,
1129129904,
1103059905,
1065059905,
1091059906,
1110149904,
1129149903,
1083029905,
1080139904,
1076109903,
1010019902,
1058019902,
1060019903,
1053019902,
1030089902,
1018149902,
1077149902,
1010109901,
1011109901,
1000119902,
1023049903,
1107119909,
1108119909,
1106119909)

Bảng trông như thế này:

CREATE TABLE dbo.[TestTable]([MPNR] [numeric](9, 0) NOT NULL)

Sự cố xảy ra mỗi khi tôi bắt đầu truy vấn. Nếu tôi giảm số lượng giá trị trong INmệnh đề, nó hoạt động. (Tất nhiên, nó không trả về hàng nào.)

Tôi biết rằng các giá trị trong INmệnh đề là các số có 10 chữ số và cột chỉ có 9 chữ số, nhưng điều đó sẽ không dẫn đến sự cố của toàn bộ phiên bản SQL Server.

Phiên bản SQL Server của tôi là 2008 R2 trên Windows Server 2003 32 bit.

Đây có phải là một lỗi được biết đến? Có bản vá cho SQL Server không?


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Paul White nói GoFundMonica

Câu trả lời:


20

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()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.75thay vì 1952thêm một hàng khác 96và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ị.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.