ลองนึกภาพว่าคุณมีโครงสร้างตารางต่อไปนี้:
LogId | ProductId | FromPositionId | ToPositionId | Date | Quantity
-----------------------------------------------------------------------------------
1 | 123 | 0 | 10002 | 2018-01-01 08:10:22 | 5
2 | 123 | 0 | 10003 | 2018-01-03 15:15:10 | 9
3 | 123 | 10002 | 10004 | 2018-01-07 21:08:56 | 3
4 | 123 | 10004 | 0 | 2018-02-09 10:03:23 | 1
FromPositionId
และToPositionId
เป็นตำแหน่งหุ้น บางตำแหน่ง ID: s 0
มีความหมายพิเศษเช่น เหตุการณ์จากหรือ0
ถึงหมายถึงว่ามีการสร้างหรือลบสต็อค จาก0
อาจเป็นสต็อคจากการส่งมอบและ0
อาจเป็นใบสั่งซื้อที่จัดส่ง
ตารางนี้ปัจจุบันมีประมาณ 5.5 ล้านแถว เราคำนวณมูลค่าสต็อคสำหรับแต่ละผลิตภัณฑ์และวางลงในตารางแคชในตารางโดยใช้แบบสอบถามที่มีลักษณะดังนี้:
WITH t AS
(
SELECT ToPositionId AS PositionId, SUM(Quantity) AS Quantity, ProductId
FROM ProductPositionLog
GROUP BY ToPositionId, ProductId
UNION
SELECT FromPositionId AS PositionId, -SUM(Quantity) AS Quantity, ProductId
FROM ProductPositionLog
GROUP BY FromPositionId, ProductId
)
SELECT t.ProductId, t.PositionId, SUM(t.Quantity) AS Quantity
FROM t
WHERE NOT t.PositionId = 0
GROUP BY t.ProductId, t.PositionId
HAVING SUM(t.Quantity) > 0
แม้ว่าสิ่งนี้จะเสร็จสิ้นภายในระยะเวลาที่เหมาะสม (ประมาณ 20 วินาที) แต่ฉันรู้สึกว่านี่เป็นวิธีที่ไม่มีประสิทธิภาพในการคำนวณมูลค่าหุ้น เราไม่ค่อยทำอะไรนอกจากINSERT
: s ในตารางนี้ แต่บางครั้งเราเข้าไปข้างในและปรับปริมาณหรือลบแถวด้วยตนเองเนื่องจากความผิดพลาดของผู้ที่สร้างแถวเหล่านี้
ฉันมีความคิดในการสร้าง "จุดตรวจสอบ" ในตารางที่แยกต่างหากคำนวณค่าจนถึงจุดเฉพาะเวลาและใช้เป็นค่าเริ่มต้นเมื่อสร้างตารางแคชปริมาณสต็อกของเรา:
ProductId | PositionId | Date | Quantity
-------------------------------------------------------
123 | 10002 | 2018-01-07 21:08:56 | 2
ความจริงที่ว่าบางครั้งเราเปลี่ยนแถวทำให้เกิดปัญหาในกรณีนี้เราต้องจำไว้ว่าให้ลบจุดตรวจสอบใด ๆ ที่สร้างขึ้นหลังจากแถวบันทึกที่เราเปลี่ยนไป สิ่งนี้สามารถแก้ไขได้โดยไม่คำนวณจุดตรวจจนถึงตอนนี้ แต่ให้เหลือหนึ่งเดือนระหว่างตอนนี้กับจุดตรวจสุดท้าย (เราไม่ค่อยทำการเปลี่ยนแปลงที่ไกลมาก)
ความจริงที่ว่าบางครั้งเราจำเป็นต้องเปลี่ยนแถวนั้นยากที่จะหลีกเลี่ยงและฉันต้องการที่จะยังคงสามารถทำสิ่งนี้ได้มันไม่ได้แสดงในโครงสร้างนี้ แต่บางครั้งเหตุการณ์บันทึกจะเชื่อมโยงกับระเบียนอื่นในตารางอื่นและเพิ่มแถวบันทึกอื่น เพื่อให้ได้ปริมาณที่เหมาะสมบางครั้งก็เป็นไปไม่ได้
ตารางบันทึกคือคุณสามารถจินตนาการได้ว่าการเติบโตค่อนข้างเร็วและเวลาในการคำนวณจะเพิ่มขึ้นตามเวลา
ดังนั้นสำหรับคำถามของฉันคุณจะแก้ปัญหานี้อย่างไร มีวิธีที่มีประสิทธิภาพมากกว่าในการคำนวณมูลค่าหุ้นปัจจุบันหรือไม่? ความคิดของฉันเกี่ยวกับจุดตรวจที่ดีหรือไม่?
เรากำลังเรียกใช้ SQL Server 2014 Web (12.0.5511)
แผนการดำเนินการ: https://www.brentozar.com/pastetheplan/?id=Bk8gyc68Q
ที่จริงฉันให้เวลาดำเนินการผิดข้างต้น 20s เป็นเวลาที่การปรับปรุงแคชที่สมบูรณ์ใช้ แบบสอบถามนี้ใช้เวลาประมาณ 6-10 วินาทีในการเรียกใช้ (8 วินาทีเมื่อฉันสร้างแผนแบบสอบถามนี้) นอกจากนี้ยังมีการเข้าร่วมในแบบสอบถามนี้ที่ไม่ได้อยู่ในคำถามเดิม