แผนแบบสอบถามที่มีตัวกรองบิตแมปอาจเป็นเรื่องยากที่จะอ่าน จากบทความ 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 การกระจายของแถวระหว่างฟังก์ชันแฮชจะให้คำแนะนำที่ดีได้อย่างไร:
จากที่ฉันสงสัยว่าคุณมีค่าซ้ำจำนวนมากสำหรับObject1.Column21
คอลัมน์ หากคอลัมน์ซ้ำเกิดขึ้นไม่อยู่ในฮิสโตแกรมสถิติสำหรับObject4.Column19
SQL Server อาจทำให้ค่าประมาณของ cardinality ผิดมาก
ฉันคิดว่าคุณควรกังวลว่าอาจเป็นไปได้ในการปรับปรุงประสิทธิภาพของแบบสอบถาม แน่นอนหากแบบสอบถามตรงตามเวลาตอบสนองหรือข้อกำหนด SLA อาจไม่คุ้มค่าที่จะทำการตรวจสอบต่อไป อย่างไรก็ตามหากคุณต้องการตรวจสอบเพิ่มเติมมีบางสิ่งที่คุณสามารถทำได้ (นอกเหนือจากการอัปเดตสถิติ) เพื่อรับทราบว่าเครื่องมือเพิ่มประสิทธิภาพข้อความค้นหาจะเลือกแผนที่ดีกว่าหากมีข้อมูลที่ดีกว่า คุณสามารถใส่ผลลัพธ์ของการเข้าร่วมระหว่างDatabase1.Schema1.Object10
และDatabase1.Schema1.Object11
ลงในตารางชั่วคราวและดูว่าคุณยังคงได้รับการเข้าร่วมวนซ้ำกัน คุณสามารถเปลี่ยนการเข้าร่วมเป็นLEFT OUTER JOIN
เครื่องมือเพิ่มประสิทธิภาพการสืบค้นจะไม่ลดจำนวนแถวในขั้นตอนนั้น คุณสามารถเพิ่มMAXDOP 1
คำใบ้ลงในคิวรีของคุณเพื่อดูว่าเกิดอะไรขึ้น คุณสามารถใช้TOP
พร้อมกับตารางที่ได้รับเพื่อบังคับให้การเข้าร่วมเป็นไปล่าสุดหรือคุณสามารถคอมเม้นท์การเข้าร่วมจากแบบสอบถาม หวังว่าคำแนะนำเหล่านี้จะเพียงพอสำหรับคุณในการเริ่มต้น
เกี่ยวกับรายการเชื่อมต่อในคำถามเป็นไปไม่ได้อย่างมากที่เกี่ยวข้องกับคำถามของคุณ ปัญหานั้นไม่เกี่ยวข้องกับการประมาณแถวที่ไม่ดี มันเกี่ยวข้องกับสภาพการแข่งขันแบบคู่ขนานที่ทำให้เกิดแถวจำนวนมากเกินไปที่จะถูกประมวลผลในแผนคิวรีที่อยู่เบื้องหลัง ที่นี่ดูเหมือนว่าข้อความค้นหาของคุณจะไม่ทำงานพิเศษใด ๆ