ทำไมการประมาณแถวของ SQL Server จึงเปลี่ยนเมื่อฉันเพิ่มคำแนะนำการเข้าร่วม


15

ฉันมีแบบสอบถามที่รวมตารางไม่กี่ตารางและทำงานได้ไม่ดีนัก - การประมาณแถวเป็นวิธีปิด (1,000 ครั้ง) และมีการเลือกการเข้าร่วมลูปซ้อนกันทำให้เกิดการสแกนหลายตาราง รูปร่างของแบบสอบถามค่อนข้างตรงไปตรงมามีลักษณะดังนี้:

SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id 
WHERE t4.id = some_GUID

เล่นรอบกับแบบสอบถามฉันสังเกตเห็นว่าเมื่อฉันบอกเป็นนัย ๆ ให้ใช้การรวม Merge สำหรับการรวมอย่างใดอย่างหนึ่งมันทำงานเร็วขึ้นหลายครั้ง สิ่งนี้ฉันสามารถเข้าใจได้ - การรวมการผสานเป็นตัวเลือกที่ดีกว่าสำหรับข้อมูลที่เข้าร่วม แต่ SQL Server ไม่คาดการณ์ว่าจะเลือก Nested Loops ได้ถูกต้อง

สิ่งที่ฉันไม่เข้าใจอย่างเต็มที่เป็นเพราะเหตุใดคำแนะนำการเข้าร่วมนี้จึงเปลี่ยนประมาณการทั้งหมดสำหรับผู้ดำเนินการแผนทั้งหมด จากการอ่านบทความและหนังสือที่แตกต่างกันฉันสันนิษฐานว่าการประเมิน cardinality ดำเนินการก่อนสร้างแผนดังนั้นการใช้คำใบ้จะไม่เปลี่ยนแปลงการประมาณ แต่บอกให้ SQL Server ใช้การเข้าร่วมแบบฟิสิคัลโดยเฉพาะ

อย่างไรก็ตามสิ่งที่ฉันเห็นคือการรวมคำใบ้ทำให้การประมาณการทั้งหมดสมบูรณ์แบบมาก ทำไมสิ่งนี้ถึงเกิดขึ้นและมีเทคนิคใด ๆ ที่ทำให้การเพิ่มประสิทธิภาพข้อความค้นหาทำการประมาณที่ดีขึ้นโดยไม่ต้องบอกใบ้ - เมื่อพิจารณาว่าสถิติอนุญาตอย่างชัดเจน

UPD: แผนการดำเนินการที่ไม่ระบุชื่อสามารถพบได้ที่นี่: https://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl=0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hoins_join.slplan?dl = 0

ฉันตรวจสอบสถิติที่ใช้โดยข้อความค้นหาทั้งสองโดยใช้ TF 3604, 9292 และ 9204 และสิ่งเหล่านั้นเหมือนกัน อย่างไรก็ตามดัชนีที่สแกน / ค้นหาแตกต่างกันระหว่างเคียวรี

นอกจากนั้นฉันพยายามเรียกใช้แบบสอบถามด้วยOPTION (FORCE ORDER)- มันทำงานเร็วกว่าการใช้การรวมแบบผสานเลือก HASH MATCH สำหรับการเข้าร่วมทุกครั้ง


3
คุณสังเกตเห็นว่าคุณมีการเข้าร่วมด้านนอก แต่จากนั้นคุณใช้ตารางในส่วนคำสั่งหรือไม่
James Z

@JamesZ - ใช่ฉันรู้แล้วฉันไม่คิดว่าจะมีปัญหาอะไร
Alexander Shelemin

9
@AlexSh ดีมีปัญหาตรรกะ / ความหมายกับที่เพราะเปลี่ยนการเข้าร่วมด้านนอกของคุณเพื่อเข้าร่วมภายใน
Aaron Bertrand

คำตอบ:


21

จากการอ่านบทความและหนังสือที่แตกต่างกันฉันคิดว่าการประเมินความสำคัญจะดำเนินการก่อนสร้างแผน

ไม่แน่นอน การประมาณค่าเชิงหัวใจเริ่มต้นนั้นได้รับ (หลังจากการทำให้เรียบง่ายและงานอื่น ๆ ) ซึ่งมีผลต่อลำดับการเข้าร่วมเริ่มต้นที่เลือกโดยเครื่องมือเพิ่มประสิทธิภาพ

อย่างไรก็ตามการสำรวจที่ตามมา (ในระหว่างการปรับให้เหมาะสมตามต้นทุน) สามารถและมักจะส่งผลให้มีการคำนวณการประมาณค่า cardinality ใหม่ CE ในภายหลังเหล่านี้อาจ 'แม่นยำ' มากหรือน้อย หากผลลัพธ์ที่คาดการณ์ต่ำกว่าเครื่องมือเพิ่มประสิทธิภาพอาจเลือกแผนที่มีราคาถูกกว่า แต่ในความเป็นจริงจะใช้เวลานานกว่านั้นมาก

โดยทั่วไปไม่มีการรับประกันว่าการประมาณค่าเชิงเลขสำหรับทรีย่อยเชิงความหมายจะให้ผลลัพธ์ที่เหมือนกัน มันเป็นกระบวนการทางสถิติหลังจากทั้งหมดและการดำเนินการบางอย่างมีการสนับสนุน CE ที่ลึกกว่าผู้อื่น

ในกรณีของคุณดูเหมือนจะมีอีกปัจจัยหนึ่ง - เครื่องมือเพิ่มประสิทธิภาพจะแนะนำ (หรือเลื่อนไปด้านบน) ด้านบนซึ่งกำหนดเป้าหมายแถวบนทรีย่อยด้านล่าง:

ส่วนย่อยของแผน

หากคุณต้องเปิดใช้งานการตั้งค่าสถานะการสืบค้นกลับ 4138 (ใน 2008 R2 หรือใหม่กว่า) คุณอาจพบการประมาณการที่สอดคล้องกับความคาดหวังมากขึ้นหรือแม้กระทั่งว่าเครื่องมือเพิ่มประสิทธิภาพจะไม่เลือกลูปซ้อนกันอีกต่อไป

อย่างไรก็ตามสิ่งที่ฉันเห็นคือการรวมคำใบ้ทำให้การประมาณการทั้งหมดสมบูรณ์แบบมาก

มีองค์ประกอบของโชคที่เกี่ยวข้องที่นี่ ผู้คนมักจะเขียนคำค้นหาหรืออย่างน้อยก็ร่วมในลำดับที่พวกเขาคาดหวังว่าพวกเขาจะดำเนินการทางร่างกาย การใช้คำใบ้เข้าร่วมนั้นมาพร้อมกับนัยFORCE ORDERดังนั้นแก้ไขคำสั่งการเข้าร่วมเพื่อให้ตรงกับแบบข้อความและปิดกฎการสำรวจเครื่องมือเพิ่มประสิทธิภาพจำนวนมากที่สามารถนำไปสู่การประเมินความซ้ำซ้อน

นอกจากนั้นฉันพยายามเรียกใช้แบบสอบถามด้วย OPTION (FORCE ORDER)- มันทำงานเร็วกว่าการใช้การรวมแบบผสานเลือก HASH MATCH สำหรับการเข้าร่วมทุกครั้ง

นี่เป็นเช่นเดียวกับการบอกใบ้การเข้าร่วม แต่ไม่ จำกัด ตัวเลือกของผู้ให้บริการการเข้าร่วมทางกายภาพ อีกครั้งหากคุณเกิดขึ้นกับการเขียนคำสั่งเข้าร่วมแบบสอบถามในทางตรรกะมันค่อนข้างเป็นไปได้ที่คุณจะได้รับแผนที่สมเหตุสมผล แน่นอนว่าคุณพลาดความสามารถของเครื่องมือเพิ่มประสิทธิภาพส่วนใหญ่ด้วยวิธีนี้ซึ่งอาจไม่ให้ผลลัพธ์ที่ดีที่สุดในสถานการณ์ทั่วไป

คุณอาจจะไม่ต้องการใช้FORCE ORDERบ่อยนักเพราะมันเป็นคำใบ้ที่ทรงพลังอย่างมาก (คำสั่ง) ที่มีเอฟเฟกต์ที่กว้างกว่าการบังคับให้ลำดับการรวมง่าย ๆ ตัวอย่างเช่นจะป้องกันเครื่องมือเพิ่มประสิทธิภาพการเคลื่อนย้ายมวลรวมรอบ ๆ และแนะนำการรวมบางส่วน ฉันแนะนำอย่างมากต่อการใช้คำแนะนำนี้ยกเว้นในกรณีที่พิเศษมาก ๆ และโดยผู้ปรับจูนผู้เชี่ยวชาญอย่างแท้จริง

การวิเคราะห์โดยละเอียดจะต้องใช้เวลามากกว่าที่ฉันมีอยู่ในขณะนี้และการเข้าถึงสำเนาของฐานข้อมูลเท่านั้น


-10

สถานที่ขัดแย้งกับด้านซ้าย
ทำไมทำให้มันยากกับเครื่องมือเพิ่มประสิทธิภาพ
เมื่อเข้าร่วมตั้งแต่ 3 ตัวขึ้นไปเครื่องมือเพิ่มประสิทธิภาพจะมีแนวโน้มที่จะป้องกันและเข้าร่วมวงวนเมื่อปกป้องหน่วยความจำ
An หรือเงื่อนไขในการเข้าร่วมก็มีแนวโน้มที่จะเข้าร่วมวง - ฉันมีหลักฐานยากที่จะเกิดขึ้นทุกครั้ง - ไม่ - ยังคงเป็นจริง
ด้วยการรวมหลายเงื่อนไขดึงจากที่ที่เข้าสู่การเข้าร่วมเมื่อคุณสามารถ

SELECT t1.id
  FROM t1
  JOIN t2 
        ON t1.id = t2.t1_id
  JOIN t3 
        ON t2.id = t3.t2_id
  JOIN t4 
        ON t3.t4_id = t4.id 
       AND t4.id = some_GUID 

หรือดียิ่งกว่านั้น - ฉันเดิมพันว่าสิ่งนี้จะตอบสนองหรือเอาชนะคำแนะนำหรือการบังคับของคุณ

SELECT t1.id
  FROM t1
  JOIN t2 
        ON t1.id = t2.t1_id
  JOIN t3 
        ON t2.id = t3.t2_id
       AND t3.t4_id = some_GUID

ปัญหาเกี่ยวกับคำแนะนำคือสำหรับข้อมูลในสถานะที่ระบุ เขียนคำค้นหาที่สะอาดและให้เครื่องมือเพิ่มประสิทธิภาพทำงานได้ บางครั้งมันก็แค่ต้องการสถิติมากขึ้นในการทำสิ่งที่ถูกต้อง แต่แล้วมันจะล็อคเข้า

ทำไมประมาณการต่างกัน แผนแตกต่างกัน เริ่มด้วยข้อความค้นหาที่ให้โอกาสในการเพิ่มประสิทธิภาพกับเครื่องมือเพิ่มประสิทธิภาพ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.