Warum führt das Batch-Modus-Fensteraggregat zu einem arithmetischen Überlauf?

11

Die folgende Abfrage führt ein Fenster SUMüber eine Spaltenspeichertabelle mit aus 1500 total rows, von denen jede den Wert 0 oder 1 hat, und überläuft den INTDatentyp. Warum passiert dies?

SELECT a, p, s, v, m, n,
    SUM(CASE WHEN n IS NULL THEN 0 ELSE 1 END)
        OVER (PARTITION BY s, v, a ORDER BY p) AS lastNonNullPartition
FROM (
    SELECT a, p, s, v, m, n,
        RANK() OVER (PARTITION BY v, s, a, p ORDER BY m) AS rank
    FROM #t /* A columnstore table with 1,500 rows */
)  x
WHERE x.rank = 1
--Msg 8115, Level 16, State 2, Line 1521
--Arithmetic overflow error converting expression to data type int.

Vollständiges Skript

In dieser Datei finden Sie ein vollständig enthaltenes Reproduktionsskript.

Abfrageplan

Hier ist ein kommentierter geschätzter Abfrageplan ( vollständiges XML beim Einfügen des Plans ).

Geben Sie hier die Bildbeschreibung ein

Ähnliche Abfragen, die erfolgreich ausgeführt werden

Wenn eine der folgenden Änderungen vorgenommen wird, tritt der Fehler nicht auf:

  • Verwenden Sie das Ablaufverfolgungsflag, 8649um einen parallelen Plan unabhängig von der Kostenschwelle für Parallelität zu bevorzugen
  • Verwenden Sie das Trace-Flag 9453, um den Stapelmodus zu deaktivieren
  • Verwenden Sie die COUNTAggregationsfunktion anstelle der SUMFunktion
  • Entfernen Sie das WHERE x.rank = 1Prädikat

Diese Abfrage wird beispielsweise erfolgreich ausgeführt:

SELECT a, p, s, v, m, n,
    SUM(CASE WHEN n IS NULL THEN 0 ELSE 1 END)
        OVER (PARTITION BY s, v, a ORDER BY p) AS lastNonNullPartition
FROM (
    SELECT a, p, s, v, m, n,
        RANK() OVER (PARTITION BY v, s, a, p ORDER BY m) AS rank
    FROM #t /* A columnstore table with 1,500 rows */
)  x
WHERE x.rank = 1
OPTION (QUERYTRACEON 9453/* Disable batch mode */) 
Geoff Patterson
quelle

Antworten:

6

Mehrere Kommentatoren konnten dieses Problem reproduzieren. Wir dachten zunächst, dass SQL Server 2017 CU10 das Problem behoben hat, stellten dann jedoch fest, dass der Fehler in allen von uns getesteten Versionen von SQL Server, einschließlich CU10, reproduziert werden kann. Einige Kommentatoren beobachteten jedoch ein Zufallselement, bei dem nicht immer dasselbe Skript den Fehler auslöste.

Da es keine logische Möglichkeit gibt, eine Summe über einen Satz nicht negativer Zahlen zu berechnen, deren maximal mögliche Summe 1.500 beträgt, kann eine 32-Bit-Ganzzahl überlaufen. Wir glauben, dass dies ein Fehler im Aggregatoperator des Batch-Modus-Fensters ist. Als neuer Operator in SQL Server 2016 kann davon ausgegangen werden, dass möglicherweise noch einige Randfälle behoben werden müssen.

Hier ist der Fehlerbericht, den wir bei Microsoft eingereicht haben.

Die Antwort war:

Dies ist in SQL Server 2019 CTP 2.1 behoben und wird in Kürze auch in der Azure SQL-Datenbank behoben.

Geoff Patterson
quelle