Pourquoi l'agrégation de fenêtres en mode batch génère-t-elle un dépassement arithmétique?


11

La requête suivante effectue un fenêtrage SUMsur une table columnstore avec 1500 total rows, dont chacun a la valeur 0 ou 1, et il déborde le INTtype de données. Pourquoi cela arrive-t-il?

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.

Script complet

Voir ce fichier pour un script de reproduction entièrement contenu.

Plan de requête

Voici un plan de requête estimé annoté ( XML complet sur Coller le plan ).

entrez la description de l'image ici

Requêtes similaires qui s'exécutent avec succès

Si l'une des modifications suivantes est effectuée, l'erreur ne se produit pas:

  • Utilisez l'indicateur de trace 8649pour préférer un plan parallèle quel que soit le seuil de coût pour le parallélisme
  • Utiliser l'indicateur de trace 9453pour désactiver le mode batch
  • Utilisez la COUNTfonction d'agrégation au lieu de la SUMfonction
  • Supprimer le WHERE x.rank = 1prédicat

Par exemple, cette requête s'exécute avec succès:

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

Réponses:


6

Plusieurs commentateurs ont pu reproduire ce problème. Nous avons d'abord pensé que SQL Server 2017 CU10 avait résolu le problème, mais nous avons constaté que l'erreur pouvait être reproduite dans toutes les versions de SQL Server que nous avons essayées, y compris CU10. Cependant, certains commentateurs ont observé un élément de chance où le même script ne déclenchait pas toujours l'erreur.

Parce qu'il n'y a aucun moyen logique que le calcul d'une somme sur un ensemble de nombres non négatifs dont la somme maximale possible soit 1 500 puisse déborder un entier de 32 bits, nous pensons que c'est un bogue dans l'opérateur d'agrégation de fenêtre en mode batch. Étant un nouvel opérateur dans SQL Server 2016, il est raisonnable de supposer qu'il pourrait encore y avoir des cas marginaux à résoudre.

Voici le rapport de bug que nous avons déposé auprès de Microsoft.

La réponse a été:

Ce problème est résolu dans SQL Server 2019 CTP 2.1 et le sera également bientôt dans Azure SQL Database.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.