En travaillant avec C # Entity Framework, j'ai remarqué un plantage de mon instance SQL Server.
J'ai pu le retrouver jusqu'à cette déclaration:
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)
Le tableau ressemble à ceci:
CREATE TABLE dbo.[TestTable]([MPNR] [numeric](9, 0) NOT NULL)
Le plantage se produit chaque fois que je lance la requête. Si je réduis le nombre de valeurs dans la IN
clause, cela fonctionne. (Il ne renvoie aucune ligne, bien sûr.)
Je suis conscient que les valeurs de la IN
clause sont des nombres à 10 chiffres et que la colonne n'a que 9 chiffres, mais cela ne devrait pas conduire à un crash de toute l'instance SQL Server.
La version de My SQL Server est 2008 R2 sur Windows Server 2003 32 bits.
Est-ce un bug connu? Existe-t-il un correctif pour SQL Server?
Réponses:
J'ai pu faire une repro sur 2008 R1 SP3 10.00.5512 mais l'installation de la dernière CU (14) l'a corrigé.
En examinant les bogues corrigés dans les versions intermédiaires, il semble que vous deviez mettre à niveau vers une version qui comprend le correctif suivant.
Violation d'accès lorsque vous exécutez une requête qui contient de nombreuses valeurs constantes dans une clause IN dans SQL Server 2008 ou SQL Server 2012
Comme vous êtes sur 2008 R2, vous aurez besoin d'au moins CU 9 pour SP1 ou CU 5 pour SP2.
La description des symptômes est quelque peu brève mais mentionne des types de données incompatibles
Il ne définit pas "beaucoup". D'après les tests que j'ai faits, je soupçonne que cela peut signifier "20 ou plus" car cela semble être le point de coupure entre deux méthodes différentes d'estimation de la cardinalité.
Le crash se produisait à l'intérieur de deux méthodes appelées par
CScaOp_In::FCalcSelectivity()
des noms tels queLoadHistogramFromXVariantArray()
etCInMemHistogram::FJoin() -> WalkHistograms()
.Pour 19 éléments de liste distincts ou moins, ces méthodes n'étaient pas du tout appelées. Un bogue similaire à SQL Sever 2000 mentionne également ce point de coupure comme significatif.
Remplissage d'une table de test avec 100 000 lignes de données de test aléatoires avec des valeurs comprises entre 0 et 1047 et un histogramme commençant comme suit
La requête
Affiche les rangées estimées de 1856.
C'est exactement ce à quoi on pourrait s'attendre en obtenant les lignes estimées pour les 19 prédicats d'égalité individuellement et en les additionnant.
La formule ne fonctionne plus après l'
20
ajout à la liste dans (les lignes estimées1902.75
plutôt que l'1952
ajout d'une autre96
au total générerait).BETWEEN
semble utiliser encore une autre méthode de calcul des estimations de cardinalité.where mpnr BETWEEN 1 AND 20
estime seulement 1829,6 lignes. Je ne sais pas comment cela est dérivé de l'histogramme montré.la source