ความจริงที่ว่าคุณกำลังเปรียบเทียบกับintegerตัวแปรนั้นไม่เกี่ยวข้อง
แผนCOUNTเสมอมีCONVERT_IMPLICIT(int,[ExprNNNN],0))ที่เป็นฉลากสำหรับการแสดงออกที่เป็นตัวแทนผลมาจากการที่ExprNNNNCOUNT
สมมติฐานของฉันได้รับเสมอว่ารหัสสำหรับCOUNTเพียงปลายขึ้นเรียกรหัสเดียวกับCOUNT_BIGและนักแสดงเป็นสิ่งที่จำเป็นในการแปลงผลจากการที่ลงกลับไปbigintint
ในความเป็นจริงจะไม่โดดเด่นแม้ในแผนแบบสอบถามจาก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 แถว
ScalarOperatorค่าที่แสดงในหน้าต่างคุณสมบัติ SSMS