Il fatto che tu lo stia confrontando con una integer
variabile è irrilevante.
Il piano per COUNT
ha sempre un CONVERT_IMPLICIT(int,[ExprNNNN],0))
dove ExprNNNN
è l'etichetta per l'espressione che rappresenta il risultato di COUNT
.
La mia ipotesi è sempre stata che il codice per COUNT
finire semplicemente chiamando lo stesso codice COUNT_BIG
e il cast è necessario per convertire il bigint
risultato di quel back down in int
.
In realtà COUNT_BIG(*)
non è nemmeno distinto nel piano di query da COUNT(*)
. Entrambi si presentano come Scalar Operator(Count(*))
.
COUNT_BIG(nullable_column)
si distingue nel piano di esecuzione, COUNT(nullable_column)
ma quest'ultimo ottiene ancora un cast implicito int
.
Alcune prove del fatto che questo è il caso sono di seguito.
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)
Questo richiede circa 7 minuti per essere eseguito sul mio desktop e restituisce quanto segue
Messaggio 8115, livello 16, stato 2, riga 1
Errore di overflow aritmetico durante la conversione dell'espressione nel tipo di dati int.
Avvertenza: il valore null viene eliminato da un'operazione aggregata o altra operazione SET.
Il che indica che il COUNT
must deve essere continuato dopo che int
sarebbe stato traboccato (a 2147483647) e l'ultima riga (2150000000) è stata elaborata COUNT
dall'operatore che ha portato al messaggio di NULL
restituzione.
A titolo di confronto, sostituire l' COUNT
espressione con i SUM(CASE WHEN N < 2150000000 THEN 1 END)
ritorni
Messaggio 8115, livello 16, stato 2, riga 1
Errore di overflow aritmetico durante la conversione dell'espressione nel tipo di dati int.
senza alcun ANSI
preavviso NULL
. Da cui concludo l'overflow si è verificato in questo caso durante l'aggregazione stessa prima che fosse raggiunta la riga 2.150.000.000.
ScalarOperator
valore mostrato nella finestra delle proprietà SSMS.