Consegui reproduzir novamente o R1 SP3 2008 10.00.5512, mas a instalação da CU (14) mais recente o corrigiu.
Revendo os erros corrigidos nas versões intermediárias, parece que você precisa atualizar para uma compilação que inclua a seguinte correção.
Violação de acesso ao executar uma consulta que contém muitos valores constantes em uma cláusula IN no SQL Server 2008 ou no SQL Server 2012
Como você está no 2008 R2, precisará de pelo menos CU 9 para SP1 ou CU 5 para SP2.
A descrição dos sintomas é um pouco breve, mas menciona tipos de dados incompatíveis
Quando você executa uma consulta que contém muitos valores constantes em uma cláusula IN no Microsoft SQL Server 2008, Microsoft SQL Server 2012 ou no Microsoft SQL Server 2008 R2, pode ocorrer uma violação de acesso.
Nota Para que o problema ocorra, as constantes na cláusula IN não podem corresponder exatamente ao tipo de dados da coluna.
Não define "muitos". Pelo teste que fiz, suspeito que isso possa significar "20 ou mais", pois esse parece ser o ponto de corte entre dois métodos diferentes de estimativa da cardinalidade.
O acidente estava ocorrendo dentro de alguns métodos chamados por CScaOp_In::FCalcSelectivity()
com nomes como LoadHistogramFromXVariantArray()
e CInMemHistogram::FJoin() -> WalkHistograms()
.
Por 19 ou menos itens de lista distintos, esses métodos não estavam sendo chamados. Um bug similar do SQL Sever 2000 também menciona esse ponto de corte como significativo.
Preencher uma tabela de teste com 100.000 linhas de dados de teste aleatórios com valores entre 0 e 1047 e um histograma começando da seguinte maneira
+--------------+------------+---------+---------------------+----------------+
| 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 |
+--------------+------------+---------+---------------------+----------------+
A pergunta
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)
Mostra linhas estimadas de 1856.
É exatamente o que seria esperado obtendo as linhas estimadas para os 19 predicados de igualdade individualmente e juntando-as.
+-------+----------------+-------+
| 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
A fórmula não funciona mais depois 20
é adicionada à lista in (linhas estimadas 1902.75
em vez da 1952
que adicionaria outra 96
ao total geraria).
BETWEEN
parece usar outro método para calcular estimativas de cardinalidade.
where mpnr BETWEEN 1 AND 20
estima apenas 1829,6 linhas. Não faço ideia de como isso é derivado do histograma mostrado.