Die Tatsache, dass Sie es mit einer integer
Variablen vergleichen, ist irrelevant.
Der Plan für hat COUNT
immer ein CONVERT_IMPLICIT(int,[ExprNNNN],0))
Wo ExprNNNN
ist die Bezeichnung für den Ausdruck, der das Ergebnis von darstellt COUNT
.
Meine Annahme war immer, dass der Code für COUNT
nur den gleichen Code aufruft wie COUNT_BIG
und die Besetzung notwendig ist, um das bigint
Ergebnis davon wieder in umzuwandeln int
.
Tatsächlich COUNT_BIG(*)
wird im Abfrageplan nicht einmal von unterschieden COUNT(*)
. Beide erscheinen als Scalar Operator(Count(*))
.
COUNT_BIG(nullable_column)
wird im Ausführungsplan von unterschieden, COUNT(nullable_column)
aber letzterer erhält immer noch eine implizite Besetzung zurück zu int
.
Einige Beweise dafür, dass dies der Fall ist, sind unten aufgeführt.
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)
Die Ausführung auf meinem Desktop dauert ca. 7 Minuten und gibt Folgendes zurück
Nachricht 8115, Ebene 16, Status 2, Zeile 1
Arithmetischer Überlauffehler beim Konvertieren des Ausdrucks in den Datentyp int.
Warnung: Der Nullwert wird durch eine aggregierte oder andere SET-Operation entfernt.
Dies zeigt an, dass das COUNT
Muss fortgesetzt werden muss, nachdem ein int
Überlauf (bei 2147483647) und die letzte Zeile (2150000000) vom COUNT
Bediener verarbeitet wurde , was zu der Nachricht über NULL
die Rückgabe führte.
Zum Vergleich: Ersetzen des COUNT
Ausdrucks durch SUM(CASE WHEN N < 2150000000 THEN 1 END)
Rückgabe
Nachricht 8115, Ebene 16, Status 2, Zeile 1
Arithmetischer Überlauffehler beim Konvertieren des Ausdrucks in den Datentyp int.
ohne ANSI
Vorwarnung NULL
. Daraus schließe ich, dass der Überlauf in diesem Fall während der Aggregation selbst stattgefunden hat, bevor die Zeile 2.150.000.000 erreicht wurde.
ScalarOperator
Wert angesehen, der im SSMS-Eigenschaftenfenster angezeigt wird.