Дивний екземпляр SQL Server виходить з ладу під час мовлення на число


20

Під час роботи з C # Entity Framework я помітив збій у моєму екземплярі SQL Server.

Я зміг простежити це до цього твердження:

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)

Таблиця виглядає так:

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

Збій відбувається щоразу, коли я запускаю запит. Якщо я зменшу кількість значень у INпункті, воно працює. (Звичайно, він не повертає жодних рядків.)

Мені відомо, що значення в INпункті - це десятизначні числа, а стовпець має лише 9 цифр, але це не повинно призводити до збоїв у всьому екземплярі SQL Server.

Версія мого SQL Server - це 2008 R2 на 32-розрядному сервері Windows Server 2003.

Це відомий Буг? Чи є патч для SQL Server?


Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
Пол Білий каже, що GoFundMonica

Відповіді:


20

Мені вдалося спростувати 2008 R1 SP3 10.00.5512, але встановлення останнього CU (14) виправило це.

Перегляд помилок, виправлених у втручаються версіях, виглядає так, ніби вам потрібно оновити до збірки, яка включає наступне виправлення.

Порушення доступу під час запуску запиту, який містить багато постійних значень у пункті IN в SQL Server 2008 або в SQL Server 2012

Коли ви перебуваєте на 2008 R2, вам знадобиться принаймні 9 CU для SP1 або CU 5 для SP2.

Опис симптомів дещо короткий, але згадуються невідповідні типи даних

Якщо ви запускаєте запит, який містить багато постійних значень у пункті IN в Microsoft SQL Server 2008, Microsoft SQL Server 2012 або в Microsoft SQL Server 2008 R2, може виникнути порушення доступу.

Примітка. Для виникнення проблеми константи пункту IN не можуть точно збігатися з типом даних стовпця.

Він не визначає "багато". Зважаючи на тестування, я підозрюю, що це може означати "20 або більше", оскільки це, здається, є межею між двома різними методами оцінки кардинальності.

Збій відбувався всередині пари методів, названих такими CScaOp_In::FCalcSelectivity()іменами, як LoadHistogramFromXVariantArray()і CInMemHistogram::FJoin() -> WalkHistograms().

Для 19 або менше окремих елементів у списку ці методи взагалі не називались. Аналогічний SQL Sever 2000 помилка також згадує про це зрізаних точках як значні.

Зарахування тестової таблиці зі 100 000 рядків випадкових даних тесту зі значеннями від 0 до 1047 та гістограмою, починаючи наступним чином

+--------------+------------+---------+---------------------+----------------+
| 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          |
+--------------+------------+---------+---------------------+----------------+

Запит

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)

Показує орієнтовні ряди 1856 року.

Це саме те, чого можна було б очікувати, отримуючи оцінені рядки для 19 предикатів рівності окремо та додаючи їх разом.

+-------+----------------+-------+
| 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

Формула більше не працює після 20додавання до списку (Орієнтовні рядки, 1902.75а не 1952додавання іншого 96до загального).

BETWEEN Схоже, використовується ще один метод розрахунку оцінок кардинальності.

where mpnr BETWEEN 1 AND 20оцінює лише 1829,6 рядків. Я не маю уявлення, як це походить від показаної гістограми.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.