ฉันมีแบบสอบถามที่ใช้select *ไม่เพียง แต่อ่านน้อยลง แต่ยังใช้เวลา CPU น้อยกว่าการใช้select c.Fooอย่างมาก
นี่คือแบบสอบถาม:
select top 1000 c.ID
from ATable a
join BTable b on b.OrderKey = a.OrderKey and b.ClientId = a.ClientId
join CTable c on c.OrderId = b.OrderId and c.ShipKey = a.ShipKey
where (a.NextAnalysisDate is null or a.NextAnalysisDate < @dateCutOff)
and b.IsVoided = 0
and c.ComplianceStatus in (3, 5)
and c.ShipmentStatus in (1, 5, 6)
order by a.LastAnalyzedDate
สิ่งนี้เสร็จสิ้นด้วยการอ่านแบบลอจิคัล 2,473,658 ตัวส่วนใหญ่ในตาราง B มันใช้ CPU 26,562 ตัวและมีระยะเวลา 7,965
นี่คือแผนแบบสอบถามที่สร้างขึ้น:
ใน PasteThePlan: https://www.brentozar.com/pastetheplan/?id=BJAp2mQIQ
เมื่อฉันเปลี่ยนc.IDไป*แบบสอบถามจบด้วย 107,049 ตรรกะอ่านธรรมกระจายอย่างสม่ำเสมอระหว่างทั้งสามตาราง มันใช้ซีพียู 4,266 ตัวและมีช่วงเวลา 1,147
นี่คือแผนแบบสอบถามที่สร้างขึ้น:
ใน PasteThePlan: https://www.brentozar.com/pastetheplan/?id=SyZYn7QUQ
ฉันพยายามใช้คำแนะนำการค้นหาที่แนะนำโดย Joe Obbish ด้วยผลลัพธ์เหล่านี้
select c.ID: https://www.brentozar.com/pastetheplan/?id=SJfBdOELm
select c.IDคำแนะนำ: https://www.brentozar.com/pastetheplan/ ? id = B1W ___ N87
select *โดยไม่มีคำใบ้: https://www.brentozar.com/pastetheplan/?id=HJ6qddEIm
select *พร้อมคำใบ้: https://www.brentozar.com/pastetheplan/?id=rJhhudNIQ
การใช้OPTION(LOOP JOIN)คำใบ้ด้วยselect c.IDนั้นลดจำนวนการอ่านลงอย่างมากเมื่อเทียบกับรุ่นที่ไม่มีคำใบ้ แต่ก็ยังคงทำประมาณ 4x จำนวนการอ่านselect *คำค้นหาโดยไม่มีคำใบ้ใด ๆ การเพิ่มOPTION(RECOMPILE, HASH JOIN)ในselect *แบบสอบถามทำให้ประสิทธิภาพแย่ลงกว่าสิ่งอื่นใดที่ฉันได้ลองไปแล้ว
หลังจากการปรับปรุงสถิติในตารางและดัชนีของตนโดยใช้WITH FULLSCANการselect c.IDแบบสอบถามกำลังทำงานได้เร็วขึ้นมาก:
select c.IDก่อนที่จะปรับปรุง: https://www.brentozar.com/pastetheplan/?id=SkiYoOEUm
select *ก่อนการปรับปรุง: https://www.brentozar.com/ pastetheplan /? id = ryrvodEUX
select c.IDหลังจากอัปเดต: https://www.brentozar.com/pastetheplan/?id=B1MRoO487
select *หลังจากอัปเดต: https://www.brentozar.com/pastetheplan/?id=Hk7si_V8m
select *ยังคงมีประสิทธิภาพสูงกว่าselect c.IDในแง่ของระยะเวลาทั้งหมดและการอ่านทั้งหมด ( select *มีประมาณครึ่งหนึ่งที่อ่าน) แต่มันใช้ CPU มากขึ้น โดยรวมแล้วพวกเขาจะเข้าใกล้กว่าก่อนการอัพเดทมาก แต่แผนยังคงแตกต่างกัน
พฤติกรรมแบบเดียวกันนั้นเห็นได้ในปี 2016 ที่ทำงานในโหมดความเข้ากันได้ในปี 2014 และในปี 2014 อะไรที่สามารถอธิบายความแตกต่างระหว่างสองแผน เป็นไปได้หรือไม่ที่ดัชนี "ถูกต้อง" ยังไม่ถูกสร้างขึ้น? สถิติที่ล้าสมัยเล็กน้อยอาจทำให้เกิดสิ่งนี้หรือไม่
ฉันพยายามย้ายภาคแสดงขึ้นเป็นONส่วนหนึ่งของการเข้าร่วมหลายวิธี แต่แผนแบบสอบถามจะเหมือนกันทุกครั้ง
หลังจากสร้างดัชนีใหม่
ฉันสร้างดัชนีทั้งหมดอีกครั้งในสามตารางที่เกี่ยวข้องในแบบสอบถาม c.IDยังคงอ่านมากที่สุด (มากกว่าสองเท่า*) แต่การใช้งาน CPU อยู่ประมาณครึ่งหนึ่งของ*รุ่น c.IDรุ่นยังหกเข้าไป tempdb ในการเรียงลำดับของATable:
c.ID: https://www.brentozar.com/pastetheplan/?id=HyHIeDO87
* : https://www.brentozar.com/pastetheplan/?id=rJ4deDOIQ
ฉันพยายามบังคับให้มันทำงานโดยไม่ขนานกันและนั่นทำให้ฉันได้รับแบบสอบถามที่มีประสิทธิภาพที่สุด: https://www.brentozar.com/pastetheplan/?id=SJn9-vuLX
ฉันสังเกตเห็นว่าจำนวนผู้ดำเนินการหลังจากดัชนีขนาดใหญ่ค้นหาที่ทำการสั่งดำเนินการเพียง 1,000 ครั้งในเวอร์ชันเธรดเดียว แต่มีความสำคัญมากกว่าในเวอร์ชันแบบขนานระหว่าง 2,622 ถึง 4,315 การดำเนินการของตัวดำเนินการต่างๆ
select c.IDสืบค้นเร็วขึ้นมาก แต่ก็ยังคงทำงานพิเศษที่การselect *สืบค้นโดยไม่ต้องใส่คำใบ้