Việc bạn so sánh nó với một integerbiến là không liên quan.
Kế hoạch cho COUNTluôn luôn có một CONVERT_IMPLICIT(int,[ExprNNNN],0))nơi ExprNNNNlà nhãn cho biểu đại diện cho các kết quả của sự COUNT.
Giả định của tôi luôn luôn là mã COUNTcuối cùng gọi cùng mã COUNT_BIGvà diễn viên là cần thiết để chuyển đổi bigintkết quả của mã đó trở lại int.
Trong thực tế COUNT_BIG(*)thậm chí không được phân biệt trong kế hoạch truy vấn từ COUNT(*). Cả hai hiện lên như Scalar Operator(Count(*)).
COUNT_BIG(nullable_column)không được phân biệt trong kế hoạch thực hiện từ COUNT(nullable_column) nhưng sau này vẫn nhận được một diễn viên ngầm quay trở lại int.
Một số bằng chứng cho thấy đây là trường hợp dưới đây.
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)
Điều này mất khoảng 7 phút để chạy trên máy tính để bàn của tôi và trả về như sau
Msg 8115, Cấp 16, Bang 2, Dòng 1
Lỗi tràn số học chuyển đổi biểu thức sang kiểu dữ liệu int.
Cảnh báo: Giá trị Null được loại bỏ bằng thao tác tổng hợp hoặc hoạt động SET khác.
Điều đó chỉ ra rằng COUNTphải tiếp tục sau khi intđã tràn (tại 2147483647) và hàng cuối cùng (2150000000) đã được xử lý bởi COUNTnhà điều hành dẫn đến thông báo về việc NULLđược trả lại.
Bằng cách so sánh thay thế COUNTbiểu thức bằng SUM(CASE WHEN N < 2150000000 THEN 1 END)trả về
Msg 8115, Cấp 16, Bang 2, Dòng 1
Lỗi tràn số học chuyển đổi biểu thức sang kiểu dữ liệu int.
không có ANSIcảnh báo về NULL. Từ đó tôi kết luận rằng sự cố tràn đã xảy ra trong trường hợp này trong quá trình tổng hợp trước khi đạt được hàng 2.150.000.000.
ScalarOperatorgiá trị được hiển thị trong cửa sổ thuộc tính SSMS.