ฉันสามารถทำซ้ำในปี 2008 R1 SP3 10.00.5512 แต่การติดตั้ง CU ล่าสุด (14) แก้ไข
การตรวจสอบข้อบกพร่องที่ได้รับการแก้ไขในเวอร์ชันที่แทรกแซงดูเหมือนว่าคุณจะต้องอัพเกรดเป็นบิลด์ที่มีการแก้ไขต่อไปนี้
การละเมิดการเข้าถึงเมื่อคุณเรียกใช้แบบสอบถามที่ประกอบด้วยค่าคงที่จำนวนมากในส่วนคำสั่ง IN ใน SQL Server 2008 หรือใน SQL Server 2012
ในขณะที่คุณอยู่บน 2008 R2 คุณจะต้องมี CU 9 เป็นอย่างต่ำสำหรับ SP1 หรือ CU 5 สำหรับ SP2
คำอธิบายอาการค่อนข้างสั้น แต่กล่าวถึงประเภทข้อมูลที่ไม่ตรงกัน
เมื่อคุณเรียกใช้แบบสอบถามที่ประกอบด้วยค่าคงที่จำนวนมากในส่วนคำสั่ง IN ใน Microsoft SQL Server 2008, Microsoft SQL Server 2012 หรือใน Microsoft SQL Server 2008 R2 การละเมิดการเข้าถึงอาจเกิดขึ้น
หมายเหตุเพื่อให้เกิดปัญหาค่าคงที่ในส่วนคำสั่ง IN ไม่สามารถจับคู่กับชนิดข้อมูลคอลัมน์ได้อย่างแม่นยำ
มันไม่ได้นิยาม "จำนวนมาก" จากการทดสอบฉันสงสัยว่านี่อาจหมายถึง "20 หรือมากกว่า" เนื่องจากนี่เป็นจุดตัดระหว่างสองวิธีที่แตกต่างกันในการประมาณค่าความเป็น cardinality
ความผิดพลาดที่เกิดขึ้นภายในไม่กี่วิธีที่เรียกว่าโดยCScaOp_In::FCalcSelectivity()
มีชื่อเช่นและLoadHistogramFromXVariantArray()
CInMemHistogram::FJoin() -> WalkHistograms()
สำหรับ 19 หรือน้อยกว่าที่แตกต่างกันในรายการรายการวิธีการเหล่านี้ไม่ได้ถูกเรียกเลย จุดบกพร่อง SQL Sever 2000 ที่คล้ายกันนี้ยังกล่าวถึงจุดตัดที่สำคัญเช่นกัน
การเติมตารางการทดสอบที่มี 100,000 ข้อมูลการทดสอบแบบสุ่มด้วยค่าระหว่าง 0 ถึง 1,047 และฮิสโตแกรมเริ่มต้นดังนี้
+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0 | 0 | 104 | 0 | 1 |
| 8 | 672 | 118 | 7 | 96 |
| 13 | 350 | 118 | 4 | 87.5 |
| 18 | 395 | 107 | 4 | 98.75 |
| 23 | 384 | 86 | 4 | 96 |
| 28 | 371 | 85 | 4 | 92.75 |
+--------------+------------+---------+---------------------+----------------+
แบบสอบถาม
SELECT * FROM dbo.[TestTable]
where mpnr in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)
option (maxdop 1)
แสดงแถวโดยประมาณ 1856
นี่คือสิ่งที่คาดหวังจากการได้รับแถวที่ประมาณไว้สำหรับความเท่าเทียมกันทั้ง 19 ข้อและแยกกันเข้าด้วยกัน
+-------+----------------+-------+
| 1-7 | AVG_RANGE_ROWS | 96 |
| 8 | EQ_ROWS | 118 |
| 9-12 | AVG_RANGE_ROWS | 87.5 |
| 13 | EQ_ROWS | 118 |
| 14-17 | AVG_RANGE_ROWS | 98.75 |
| 18 | EQ_ROWS | 107 |
| 19 | AVG_RANGE_ROWS | 96 |
+-------+----------------+-------+
7*96 + 118 + 4*87.5 + 118 + 4*98.75 + 107 + 1*96 = 1856
สูตรจะไม่ทำงานหลังจาก20
ถูกเพิ่มลงในรายการใน (แถวโดยประมาณ1902.75
แทนที่จะ1952
เพิ่ม96
เข้าไปในผลรวมจะสร้าง)
BETWEEN
ดูเหมือนว่าจะใช้วิธีการอื่นในการคำนวณค่าประมาณของ cardinality
where mpnr BETWEEN 1 AND 20
ประมาณเพียง 1,829.6 แถว ฉันไม่รู้ว่ามันมาจากฮิสโตแกรมที่แสดง