배치 모드 창 집계에서 산술 오버플로가 발생하는 이유는 무엇입니까?


11

다음 쿼리 는 값이 0 또는 1 인 SUMcolumnstore 테이블에 대해 창 을 표시하며 데이터 유형을 1500 total rows오버플로합니다 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.

전체 스크립트

완전히 포함 된 재생산 스크립트에 대해서는이 파일을 참조하십시오.

쿼리 계획

다음은 주석이 달린 추정 쿼리 계획입니다 (계획 에 붙여 넣기에 대한 전체 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의 새로운 연산자이기 때문에 여전히 해결해야 할 몇 가지 사례가 있다고 가정하는 것이 합리적입니다.

다음은 Microsoft에 제출 한 버그 보고서입니다.

응답은 다음과 같습니다.

이것은 SQL Server 2019 CTP 2.1에서 수정되었으며 곧 Azure SQL Database에서도 수정 될 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.