Seltsamer SQL Server-Instanzabsturz beim Umsetzen auf numerisch

20

Während der Arbeit mit C # Entity Framework ist mir ein Absturz meiner SQL Server-Instanz aufgefallen.

Ich konnte es auf diese Aussage zurückführen:

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)

Die Tabelle sieht folgendermaßen aus:

CREATE TABLE dbo.[TestTable]([MPNR] [numeric](9, 0) NOT NULL)

Der Absturz tritt jedes Mal auf, wenn ich die Abfrage starte. Wenn ich die Anzahl der Werte in der INKlausel reduziere , funktioniert es. (Es werden natürlich keine Zeilen zurückgegeben.)

Mir ist bekannt, dass die Werte in der INKlausel 10-stellige Zahlen sind und die Spalte nur 9-stellig ist. Dies sollte jedoch nicht zu einem Absturz der gesamten SQL Server-Instanz führen.

Die Version von My SQL Server ist 2008 R2 unter Windows Server 2003 32-Bit.

Ist das ein bekannter Bug? Gibt es einen Patch für SQL Server?

SteLoe
quelle
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Paul White sagt GoFundMonica

Antworten:

20

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 20zu dem in der Liste hinzugefügt wird (Geschätzte Zeilen 1902.75anstatt das , 1952dass eine anderen Zusatz 96zur Gesamt erzeugen würde).

BETWEEN scheint noch eine andere Methode zur Berechnung von Kardinalitätsschätzungen zu verwenden.

where mpnr BETWEEN 1 AND 20schätzt nur 1829,6 Zeilen. Ich habe keine Ahnung, wie sich das aus dem gezeigten Histogramm ergibt.

Martin Smith
quelle