Те, що ви порівнюєте його зі integer
змінною, не має значення.
План COUNT
завжди має те, CONVERT_IMPLICIT(int,[ExprNNNN],0))
де ExprNNNN
є мітка для виразу, що представляє результат COUNT
.
Моє припущення завжди було таким, що код для COUNT
просто закінчується викликом того самого коду, що COUNT_BIG
і виклик необхідний для перетворення bigint
результату цього назад вниз int
.
Насправді COUNT_BIG(*)
навіть не відрізняється в плані запиту від COUNT(*)
. Обидва проявляються як Scalar Operator(Count(*))
.
COUNT_BIG(nullable_column)
насправді відрізняють у плані виконання, COUNT(nullable_column)
але останній все одно має неявний відкид int
.
Деякі докази того, що це справа, наведені нижче.
WITH
E1(N) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
) -- 1*10^1 or 10 rows
, E2(N) AS (SELECT 1 FROM E1 a, E1 b) -- 1*10^2 or 100 rows
, E4(N) AS (SELECT 1 FROM E2 a, E2 b) -- 1*10^4 or 10,000 rows
, E8(N) AS (SELECT 1 FROM E4 a, E4 b) -- 1*10^8 or 100,000,000 rows
, E16(N) AS (SELECT 1 FROM E8 a, E8 b) -- 1*10^16 or 10,000,000,000,000,000 rows
, T(N) AS (SELECT TOP (2150000000)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS N FROM E16)
SELECT COUNT(CASE WHEN N < 2150000000 THEN 1 END)
FROM T
OPTION (MAXDOP 1)
На моєму робочому столі потрібно близько 7 хвилин і повертає наступне
Msg 8115, рівень 16, стан 2, рядок 1
Арифметична помилка переповнення перетворення виразу в тип даних int.
Попередження: Нульове значення усувається за допомогою сукупної або іншої операції SET.
Що вказує на те, що COUNT
необхідно продовжити після того, як int
переповнюється (на 2147483647), і останній рядок (2150000000) обробляється COUNT
оператором, що призводить до повідомлення про NULL
повернення.
Для порівняння, замінюючи COUNT
вираз SUM(CASE WHEN N < 2150000000 THEN 1 END)
поверненнями
Msg 8115, рівень 16, стан 2, рядок 1
Арифметична помилка переповнення перетворення виразу в тип даних int.
без ANSI
попередження про NULL
. Звідки я роблю висновок, що в цьому випадку переповнення сталося під час самої агрегації до досягнення рядів 2 150 000 000.
ScalarOperator
значення, показане у вікні властивостей SSMS.