ทำไมตัวดำเนินการแบบขนาน (Repartition Streams) จะลดการประมาณแถวเป็น 1


12

ฉันใช้ SQL Server 2012 Enterprise ฉันเจอแผน SQL ที่แสดงพฤติกรรมบางอย่างที่ฉันไม่พบว่าใช้งานง่าย หลังจากการดำเนินการสแกนดัชนีแบบขนานขนาดใหญ่การดำเนินการแบบขนาน (Repartition Streams) เกิดขึ้น แต่กำลังฆ่าการประมาณแถวที่ถูกส่งคืนโดยดัชนีการสแกน (Object10.Index2) ลดการประมาณการเป็น 1 ฉันได้ทำการค้นหาบางอย่างแล้ว แต่ ยังไม่เจออะไรที่อธิบายพฤติกรรมนี้ แบบสอบถามค่อนข้างง่ายแม้ว่าแต่ละตารางจะมีระเบียนเป็นล้าน ๆ นี่เป็นส่วนหนึ่งของกระบวนการโหลด DWH และชุดข้อมูลระดับกลางนี้มีการแตะสองสามครั้งตลอด แต่คำถามที่ฉันมีเกี่ยวข้องกับการประมาณแถวโดยเฉพาะ บางคนสามารถอธิบายได้หรือไม่ว่าเหตุใดการประมาณแถวที่ถูกต้องจึงไปที่ 1 ในตัวดำเนินการขนาน (Repartition Strems) นอกจากนี้

ฉันได้ส่งแผนเต็มรูปแบบเพื่อวางแผน

นี่คือการดำเนินการที่เป็นปัญหา:

ป้อนคำอธิบายรูปภาพที่นี่

รวมแผนผังต้นไม้ในกรณีที่เพิ่มบริบทเพิ่มเติม:

ป้อนคำอธิบายรูปภาพที่นี่

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

คำตอบ:


9

แผนแบบสอบถามที่มีตัวกรองบิตแมปอาจเป็นเรื่องยากที่จะอ่าน จากบทความ BOL สำหรับการแบ่งสตรีม (เน้นที่เหมือง):

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

นอกจากนี้บทความเกี่ยวกับตัวกรองบิตแมปก็มีประโยชน์เช่นกัน:

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

ฉันเชื่อว่านั่นคือสิ่งที่คุณสังเกตเห็นจากการค้นหา เป็นไปได้ที่จะมีการสาธิตที่ค่อนข้างง่ายเพื่อแสดงตัวดำเนินการ repartition stream ลดการประเมิน cardinality แม้ว่าเมื่อตัวดำเนินการ bitmap IN_ROWเทียบกับตารางข้อเท็จจริง การเตรียมข้อมูล:

create table outer_tbl (ID BIGINT NOT NULL);

INSERT INTO outer_tbl WITH (TABLOCK)
SELECT TOP (1000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values;

create table inner_tbl_1 (ID BIGINT NULL);
create table inner_tbl_2 (ID BIGINT NULL);

INSERT INTO inner_tbl_1 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

INSERT INTO inner_tbl_2 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

นี่คือแบบสอบถามที่คุณไม่ควรเรียกใช้:

SELECT *
FROM outer_tbl o
INNER JOIN inner_tbl_1 i ON o.ID = i.ID
INNER JOIN inner_tbl_2 i2 ON o.ID = i2.ID
OPTION (HASH JOIN, QUERYTRACEON 9481, QUERYTRACEON 8649);

ผมอัปโหลดแผน ดูผู้ประกอบการที่อยู่ใกล้กับinner_tbl_2:

แบ่งพาร์ทิชันการสูญเสียแถว

คุณอาจพบว่าการทดสอบครั้งที่สองในHash Joins ในคอลัมน์ Nullableโดย Paul White มีประโยชน์

มีความไม่สอดคล้องกันบางประการในการใช้การลดแถว ฉันสามารถดูได้ในแผนที่มีตารางอย่างน้อยสามตารางเท่านั้น อย่างไรก็ตามการลดลงของแถวที่คาดว่าจะสมเหตุสมผลกับการกระจายข้อมูลที่ถูกต้อง สมมติว่าคอลัมน์เข้าร่วมในตารางความเป็นจริงมีค่าซ้ำหลายอย่างที่ไม่ปรากฏในตารางมิติ ตัวกรองบิตแมปอาจกำจัดแถวเหล่านั้นก่อนที่จะถึงการเข้าร่วม สำหรับแบบสอบถามของคุณค่าประมาณจะลดลงจนถึง 1 การกระจายของแถวระหว่างฟังก์ชันแฮชจะให้คำแนะนำที่ดีได้อย่างไร:

distro แถว

จากที่ฉันสงสัยว่าคุณมีค่าซ้ำจำนวนมากสำหรับObject1.Column21คอลัมน์ หากคอลัมน์ซ้ำเกิดขึ้นไม่อยู่ในฮิสโตแกรมสถิติสำหรับObject4.Column19SQL Server อาจทำให้ค่าประมาณของ cardinality ผิดมาก

ฉันคิดว่าคุณควรกังวลว่าอาจเป็นไปได้ในการปรับปรุงประสิทธิภาพของแบบสอบถาม แน่นอนหากแบบสอบถามตรงตามเวลาตอบสนองหรือข้อกำหนด SLA อาจไม่คุ้มค่าที่จะทำการตรวจสอบต่อไป อย่างไรก็ตามหากคุณต้องการตรวจสอบเพิ่มเติมมีบางสิ่งที่คุณสามารถทำได้ (นอกเหนือจากการอัปเดตสถิติ) เพื่อรับทราบว่าเครื่องมือเพิ่มประสิทธิภาพข้อความค้นหาจะเลือกแผนที่ดีกว่าหากมีข้อมูลที่ดีกว่า คุณสามารถใส่ผลลัพธ์ของการเข้าร่วมระหว่างDatabase1.Schema1.Object10และDatabase1.Schema1.Object11ลงในตารางชั่วคราวและดูว่าคุณยังคงได้รับการเข้าร่วมวนซ้ำกัน คุณสามารถเปลี่ยนการเข้าร่วมเป็นLEFT OUTER JOINเครื่องมือเพิ่มประสิทธิภาพการสืบค้นจะไม่ลดจำนวนแถวในขั้นตอนนั้น คุณสามารถเพิ่มMAXDOP 1คำใบ้ลงในคิวรีของคุณเพื่อดูว่าเกิดอะไรขึ้น คุณสามารถใช้TOPพร้อมกับตารางที่ได้รับเพื่อบังคับให้การเข้าร่วมเป็นไปล่าสุดหรือคุณสามารถคอมเม้นท์การเข้าร่วมจากแบบสอบถาม หวังว่าคำแนะนำเหล่านี้จะเพียงพอสำหรับคุณในการเริ่มต้น

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


6

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

ในกรณีหลังการแก้ไข: ประสิทธิภาพไม่ดีเมื่อคุณเรียกใช้แบบสอบถามที่ประกอบด้วยความสัมพันธ์และเพรดิเคตใน SQL Server 2008 หรือใน SQL Server 2008 R2 หรือใน SQL Server 2012อาจเกี่ยวข้องกับการใช้การติดตามค่าสถานะ 4137 ที่รองรับ ติดตามการตั้งค่าสถานะ 4199 เพื่อเปิดใช้งานการแก้ไขเครื่องมือเพิ่มประสิทธิภาพและ / หรือ 2301 เพื่อเปิดใช้งานส่วนขยายแบบจำลอง เป็นการยากที่จะรู้บนพื้นฐานของแผนที่ไม่ระบุชื่อ

การปรากฏตัวของบิตแมปไม่ได้ส่งผลกระทบโดยตรงต่อการประเมินการเข้าร่วมของ cardinality แต่มันจะทำให้เอฟเฟ็กต์มองเห็นได้เร็วขึ้นโดยใช้การลดเซมิไฟน์ก่อน หากไม่มีบิตแมปการประมาณความน่าจะเป็นของการเข้าร่วมครั้งแรกจะเท่ากันและส่วนที่เหลือของแผนจะยังคงได้รับการปรับให้เหมาะสม

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

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

อ่านเพิ่มเติมเกี่ยวกับบิตแมปและแฮเข้าร่วม:


0

ตอบกลับคุณใน Twitter ฉันดู XML ที่แนบมาและดูความเท่าเทียมกันที่ไม่สมดุล 1 เธรดมีแถวจริงเกือบทั้งหมดในขณะที่แถวอื่นส่วนใหญ่ไม่มี เสียงกรีดร้องที่ไม่สมดุลนั้นกำลังเกิดขึ้น ดังนั้นฉันจะพิจารณาถึงคีย์ / ค่าการเข้าร่วมและสถิติและความสำคัญของมัน

ตามแนวคิดอื่น ๆ ของคุณฉันไม่แน่ใจว่าจะใช้รายการเชื่อมต่อเนื่องจากแผนวางของคุณไม่มี TOP ทุกที่ที่ฉันเห็น

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