ฉันมีแบบสอบถามที่ใช้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 *
สืบค้นโดยไม่ต้องใส่คำใบ้