¿Por qué el agregado de la ventana del modo por lotes produce un desbordamiento aritmético?


11

La siguiente consulta realiza una ventana SUMsobre una tabla de almacén de columnas 1500 total rows, cada una de las cuales tiene el valor 0 o 1, y desborda el INTtipo de datos. ¿Por qué está pasando esto?

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.

Guión completo

Consulte este archivo para ver un script de reproducción totalmente contenido.

Plan de consulta

Aquí hay un plan de consulta estimado anotado ( XML completo en Pegar el plan ).

ingrese la descripción de la imagen aquí

Consultas similares que se ejecutan con éxito

Si se realiza alguna de las siguientes modificaciones, no se produce el error:

  • Use la marca de seguimiento 8649para preferir un plan paralelo independientemente del umbral de costo para el paralelismo
  • Use la marca de seguimiento 9453para deshabilitar el modo por lotes
  • Use la COUNTfunción de agregación en lugar de la SUMfunción
  • Eliminar el WHERE x.rank = 1predicado

Por ejemplo, esta consulta se ejecuta con éxito:

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

Respuestas:


6

Varios comentaristas han podido reproducir este problema. Inicialmente pensamos que SQL Server 2017 CU10 resolvió el problema, pero luego descubrimos que el error puede reproducirse en todas las versiones de SQL Server que probamos, incluida CU10. Sin embargo, algunos comentaristas observaron un elemento de azar en el que el mismo script no siempre desencadenaba el error.

Debido a que no hay una forma lógica de que calcular una suma a través de un conjunto de números no negativos cuya suma máxima posible sea 1,500 pueda desbordar un entero de 32 bits, creemos que esto es un error en el operador agregado de la ventana del modo por lotes. Al ser un nuevo operador en SQL Server 2016, es razonable suponer que todavía podría haber algunos casos extremos para resolver.

Aquí está el informe de error que presentamos con Microsoft.

La respuesta fue:

Esto se solucionó en SQL Server 2019 CTP 2.1 y también se solucionará pronto en Azure SQL Database.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.