Fakta bahwa Anda membandingkannya dengan suatu integer
variabel tidak relevan.
Rencana untuk COUNT
selalu memiliki di CONVERT_IMPLICIT(int,[ExprNNNN],0))
mana ExprNNNN
adalah label untuk ekspresi yang mewakili hasil dari COUNT
.
Asumsi saya selalu bahwa kode untuk COUNT
akhirnya hanya memanggil kode yang sama COUNT_BIG
dan para pemain diperlukan untuk mengkonversi bigint
hasil itu kembali ke int
.
Bahkan COUNT_BIG(*)
tidak dibedakan dalam rencana kueri dari COUNT(*)
. Keduanya muncul sebagai Scalar Operator(Count(*))
.
COUNT_BIG(nullable_column)
tidak dibedakan dalam rencana eksekusi dari COUNT(nullable_column)
tetapi yang terakhir masih mendapat pemeran implisit kembali ke int
.
Beberapa bukti bahwa ini adalah kasus di bawah ini.
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)
Ini membutuhkan waktu sekitar 7 menit untuk berjalan di desktop saya dan mengembalikan yang berikut
Msg 8115, Level 16, Negara 2, Baris 1
Kesalahan aritmatika overflow mengubah ekspresi ke int tipe data.
Peringatan: Nilai kosong dihilangkan dengan agregat atau operasi SET lainnya.
Yang menunjukkan bahwa COUNT
harus dilanjutkan setelah int
akan meluap (pada 2147483647) dan baris terakhir (2150000000) diproses oleh COUNT
operator yang mengarah ke pesan tentang NULL
dikembalikan.
Dengan cara perbandingan mengganti COUNT
ekspresi dengan SUM(CASE WHEN N < 2150000000 THEN 1 END)
pengembalian
Msg 8115, Level 16, Negara 2, Baris 1
Kesalahan aritmatika overflow mengubah ekspresi ke int tipe data.
tanpa ANSI
peringatan NULL
. Dari yang saya simpulkan, limpahan yang terjadi dalam kasus ini selama agregasi sendiri sebelum baris 2.150.000.000 tercapai.
ScalarOperator
nilai yang ditampilkan di jendela properti SSMS.