Enquanto trabalhava com o C# Entity Framework, notei uma falha na minha instância do SQL Server.
Eu fui capaz de rastreá-lo para esta declaração:
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)
A tabela fica assim:
CREATE TABLE dbo.[TestTable]([MPNR] [numeric](9, 0) NOT NULL)
A falha ocorre toda vez que inicio a consulta. Se eu reduzir o número de valores dentro da IN
cláusula, funciona. (Ele não retorna nenhuma linha, é claro.)
Estou ciente de que os valores na IN
cláusula são números de 10 dígitos e a coluna tem apenas 9 dígitos, mas isso não deve levar a uma falha de toda a instância do SQL Server.
A versão do meu SQL Server é 2008 R2 em um Windows Server 2003 de 32 bits.
Isto é um erro conhecido? Existe um patch para o SQL Server?
Consegui reproduzir em 2008 R1 SP3 10.00.5512, mas a instalação da CU mais recente (14) corrigiu.
Revendo os bugs corrigidos nas versões intermediárias, parece que você precisa atualizar para uma compilação que inclui 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 tanto breve, mas menciona tipos de dados incompatíveis
Não define "muitos". Pelos testes que fiz, suspeito que isso possa significar "20 ou mais", pois parece ser o ponto de corte entre dois métodos diferentes de estimar a cardinalidade.
A falha estava acontecendo dentro de alguns métodos chamados por
CScaOp_In::FCalcSelectivity()
com nomes comoLoadHistogramFromXVariantArray()
eCInMemHistogram::FJoin() -> WalkHistograms()
.Para 19 ou menos itens distintos na lista, esses métodos não eram chamados. Um bug semelhante do SQL Server 2000 também menciona esse ponto de corte como significativo.
Preenchendo uma tabela de teste com 100.000 linhas de dados de teste aleatórios com valores entre 0 e 1.047 e um histograma começando da seguinte maneira
A pergunta
Mostra linhas estimadas de 1856.
Isso é exatamente o que seria esperado obtendo as linhas estimadas para os 19 predicados de igualdade individualmente e adicionando-as.
A fórmula não funciona mais depois que
20
é adicionada à lista (linhas estimadas1902.75
em vez da1952
que a adição de outra96
ao total geraria).BETWEEN
parece usar ainda outro método de cálculo de estimativas de cardinalidade.where mpnr BETWEEN 1 AND 20
estima apenas 1829,6 linhas. Não tenho ideia de como isso é derivado do histograma mostrado.