ฉันมีปัญหานี้มานานแล้วฉันพบวิธีแก้ปัญหาที่เหมาะกับฉันและลืมมันไป
แต่ตอนนี้มีคำถามนั้นดังนั้นฉันยินดีที่จะทำให้ปัญหานี้เกิดขึ้น
มีมุมมองที่รวมตารางบางอย่างในทางตรงไปตรงมามาก (คำสั่ง + คำสั่งซื้อ)
เมื่อถูกสอบถามโดยไม่มีwhere
ประโยคมุมมองจะส่งกลับหลายล้านบรรทัด
อย่างไรก็ตามไม่มีใครเคยเรียกมันว่าอย่างนั้น แบบสอบถามปกติคือ
select * from that_nasty_view where order_number = 123456;
สิ่งนี้จะส่งกลับประมาณ 10 ระเบียนจาก 5m
สิ่งสำคัญ: มุมมองมีฟังก์ชั่นหน้าต่างrank()
ซึ่งแบ่งพาร์ติชันตามฟิลด์โดยใช้มุมมองที่ถูกสอบถามเสมอ:
rank() over (partition by order_number order by detail_line_number)
ตอนนี้ถ้ามุมมองนี้ถูกสอบถามด้วยพารามิเตอร์ที่แท้จริงในสตริงแบบสอบถามตรงตามที่แสดงข้างต้นก็จะส่งกลับแถวทันที แผนการดำเนินการเป็นเรื่องปกติ:
- ดัชนีค้นหาทั้งสองตารางโดยใช้ดัชนีบน
order_number
(ส่งคืน 10 แถว) - การคำนวณหน้าต่างเหนือผลลัพธ์เล็ก ๆ ที่ส่งคืน
- การเลือก
อย่างไรก็ตามเมื่อมีการเรียกใช้มุมมองในแบบที่กำหนดสิ่งต่าง ๆ น่ารังเกียจ:
Index scan
บนตารางทั้งหมดที่ละเว้นดัชนี ส่งคืนแถว 5 ม.- เข้าร่วมมาก
- การคำนวณหน้าต่างทั้งหมด
partition
s (ประมาณ 500k windows) Filter
เพื่อใช้ 10 แถวจาก 5m- เลือก
สิ่งนี้เกิดขึ้นในทุกกรณีเมื่อเกี่ยวข้องกับพารามิเตอร์ มันสามารถ SSMS:
declare @order_number int = 123456;
select * from that_nasty_view where order_number = @order_number;
มันสามารถเป็นไคลเอนต์ ODBC เช่น Excel:
select * from that_nasty_view where order_number = ?
หรืออาจเป็นไคลเอนต์อื่น ๆ ที่ใช้พารามิเตอร์และไม่ใช่การต่อข้อมูล sql
หากฟังก์ชั่นหน้าต่างถูกลบออกจากมุมมองมันจะทำงานได้อย่างรวดเร็วอย่างสมบูรณ์โดยไม่คำนึงว่าจะมีการสอบถามพารามิเตอร์หรือไม่
วิธีแก้ปัญหาของฉันคือการลบฟังก์ชั่นที่กระทำผิดและนำไปใช้ใหม่ในภายหลัง
แต่จะให้อะไร มันเป็นข้อบกพร่องอย่างแท้จริงในวิธีที่ SQL Server 2008 จัดการกับฟังก์ชั่นหน้าต่างหรือไม่?
order_number
ไม่ใช่คีย์หลัก มันอยู่int not null
กับดัชนี nonclustered ในทั้งสองตาราง
OPTION (RECOMPILE)
ความช่วยเหลือ?