integer変数と比較しているという事実は関係ありません。
のプランにはCOUNT常にCONVERT_IMPLICIT(int,[ExprNNNN],0))where 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に変換する算術オーバーフローエラー。
警告:Null値は、集計またはその他のSET操作によって削除されます。
これは、がオーバーフローCOUNTした後int(2147483647)、最後の行(2150000000)がCOUNTオペレーターによって処理され、NULL返されたというメッセージが表示された後も、が継続している必要があることを示しています。
比較のために置き換えCOUNTて表現をSUM(CASE WHEN N < 2150000000 THEN 1 END)返します
メッセージ8115、レベル16、状態2、行1
式をデータ型intに変換する算術オーバーフローエラー。
ANSIに関する警告なしNULL。この場合、行自体が行2,150,000,000に達する前の集計中にオーバーフローが発生したと結論付けます。
ScalarOperatorSSMSのプロパティウィンドウに表示される値を見ていました。