バッチモードのウィンドウ集計で算術オーバーフローが発生するのはなぜですか?


11

次のクエリは、SUM列ストアテーブルに対してウィンドウ処理を実行します1500 total rows。それぞれの値は0または1であり、INTデータ型をオーバーフローします。なんでこんなことが起こっているの?

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.

完全なスクリプト

完全に含まれている再現スクリプトについては、このファイルを参照してください。

クエリプラン

これは、注釈付きの推定クエリプランです(Paste the Planの完全なXML)。

ここに画像の説明を入力してください

正常に実行される同様のクエリ

次のいずれかの変更が行われた場合、エラーは発生しません。

  • 8649並列処理のコストしきい値に関係なく、トレースフラグを使用して並列プランを優先する
  • トレースフラグ9453を使用してバッチモードを無効にする
  • 使用COUNTするのではなく、集計関数をSUM機能
  • WHERE x.rank = 1述語を削除する

たとえば、次のクエリは正常に実行されます。

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 */) 

回答:


6

複数のコメント者がこの問題を再現できました。SQL Server 2017 CU10が問題を解決したと当初は考えていましたが、CU10を含め、試行したすべてのバージョンのSQL Serverでエラーが再現されることがわかりました。ただし、一部のコメンターは、同じスクリプトが常にエラーをトリガーするとは限らない可能性のある要素を観察しました。

最大可能合計が1,500である非負の数値のセット全体で合計を計算することが32ビット整数をオーバーフローする可能性がある論理的な方法がないため、これはバッチモードのウィンドウ集約演算子のバグであると考えられます。SQL Server 2016の新しいオペレーターであるため、解決すべきエッジケースがまだある可能性があると想定するのは妥当です。

これがマイクロソフトに提出したバグレポートです。

応答は:

これはSQL Server 2019 CTP 2.1で修正されており、Azure SQL Databaseでもまもなく修正される予定です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.