Ich war in der Lage, 2008 R1 SP3 10.00.5512 zu reproduzieren, aber das Installieren der neuesten CU (14) reparierte es.
Wenn Sie die in den vorherigen Versionen behobenen Fehler überprüfen, müssen Sie anscheinend ein Upgrade auf einen Build durchführen, der die folgende Korrektur enthält.
Zugriffsverletzung, wenn Sie eine Abfrage ausführen, die viele konstante Werte in einer IN-Klausel in SQL Server 2008 oder SQL Server 2012 enthält
Da Sie 2008 R2 verwenden, benötigen Sie mindestens CU 9 für SP1 oder CU 5 für SP2.
Die Beschreibung der Symptome ist etwas kurz, erwähnt jedoch nicht übereinstimmende Datentypen
Wenn Sie eine Abfrage ausführen, die viele konstante Werte in einer IN-Klausel in Microsoft SQL Server 2008, Microsoft SQL Server 2012 oder Microsoft SQL Server 2008 R2 enthält, kann eine Zugriffsverletzung auftreten.
Hinweis: Damit das Problem auftritt, können die Konstanten in der IN-Klausel nicht genau mit dem Spaltendatentyp übereinstimmen.
Es definiert nicht "viele". Aus den Tests, die ich durchgeführt habe, habe ich den Verdacht, dass dies "20 oder mehr" bedeuten könnte, da dies der Grenzpunkt zwischen zwei verschiedenen Methoden zur Schätzung der Kardinalität zu sein scheint.
Der Absturz ereignete sich in einigen Methoden, die CScaOp_In::FCalcSelectivity()
mit Namen wie LoadHistogramFromXVariantArray()
und aufgerufen wurden CInMemHistogram::FJoin() -> WalkHistograms()
.
Für 19 oder weniger verschiedene Listenelemente wurden diese Methoden überhaupt nicht aufgerufen. Ein ähnlicher Fehler in SQL Server 2000 erwähnt diesen Grenzwert ebenfalls als erheblich.
Füllen einer Testtabelle mit 100.000 Zeilen mit zufälligen Testdaten mit Werten zwischen 0 und 1047 und einem Histogramm, das wie folgt beginnt
+--------------+------------+---------+---------------------+----------------+
| 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 |
+--------------+------------+---------+---------------------+----------------+
Die Abfrage
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)
Zeigt geschätzte Zeilen von 1856.
Dies ist genau das, was zu erwarten wäre, wenn die geschätzten Zeilen für die 19 Gleichheitsvergleichselemente einzeln abgerufen und addiert würden.
+-------+----------------+-------+
| 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
Die Formel funktioniert nicht mehr nach 20
zu dem in der Liste hinzugefügt wird (Geschätzte Zeilen 1902.75
anstatt das , 1952
dass eine anderen Zusatz 96
zur Gesamt erzeugen würde).
BETWEEN
scheint noch eine andere Methode zur Berechnung von Kardinalitätsschätzungen zu verwenden.
where mpnr BETWEEN 1 AND 20
schätzt nur 1829,6 Zeilen. Ich habe keine Ahnung, wie sich das aus dem gezeigten Histogramm ergibt.