Тот факт, что вы сравниваете его с 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 минут для запуска на моем рабочем столе и возвращает следующее
Сообщение 8115, уровень 16, состояние 2, строка 1
Ошибка арифметического переполнения при преобразовании выражения в тип данных int.
Предупреждение: нулевое значение устраняется с помощью агрегата или другой операции SET.
Это указывает на то, что COUNTдолжен был продолжаться после intпереполнения (в 2147483647) и последняя строка (2150000000) был обработан COUNTоператором, что привело к сообщению о NULLвозвращении.
Для сравнения заменим COUNTвыражение на SUM(CASE WHEN N < 2150000000 THEN 1 END)return
Сообщение 8115, уровень 16, состояние 2, строка 1
Ошибка арифметического переполнения при преобразовании выражения в тип данных int.
без ANSIпредупреждения о NULL. Из чего я делаю вывод, что переполнение произошло в этом случае во время самой агрегации до достижения строки 2 150 000 000.
ScalarOperatorзначение, показанное в окне свойств SSMS.