Мені вдалося спростувати 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 рядків. Я не маю уявлення, як це походить від показаної гістограми.