เครื่องมือเพิ่มประสิทธิภาพของ SQL Server ประมาณจำนวนแถวในตารางที่เข้าร่วมอย่างไร


13

ฉันใช้คำค้นหานี้ในฐานข้อมูลAdventureWorks2012 :

SELECT 
    s.SalesOrderID,
    d.CarrierTrackingNumber,
    d.ProductID,
    d.OrderQty
FROM Sales.SalesOrderHeader s 
JOIN Sales.SalesOrderDetail d 
    ON s.SalesOrderID = d.SalesOrderID
WHERE s.CustomerID = 11077

ถ้าฉันดูแผนการดำเนินการโดยประมาณฉันจะเห็นสิ่งต่อไปนี้:

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

การค้นหาดัชนีเริ่มต้น (ด้านบนขวา) ใช้ดัชนี IX_SalesOrderHeader_CustomerID และค้นหาตามตัวอักษร 11077 โดยมีค่าประมาณ 2.6192 แถว

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

ถ้าฉันใช้DBCC SHOW_STATISTICS ('Sales.SalesOrderHeader', 'IX_SalesOrderHeader_CustomerID') WITH HISTOGRAMมันแสดงว่าค่า 11077 อยู่ระหว่างสองคีย์ตัวอย่าง 11019 และ 11091

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

จำนวนเฉลี่ยของแถวที่แตกต่างระหว่าง 11019 และ 11091 คือ 2.619718 หรือปัดเศษเป็น 2.61972 ซึ่งเป็นค่าของแถวโดยประมาณที่แสดงสำหรับการค้นหาดัชนี

ส่วนที่ฉันไม่เข้าใจคือจำนวนแถวโดยประมาณสำหรับดัชนีคลัสเตอร์ที่ค้นหากับตาราง SalesOrderDetail

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

ถ้าฉันวิ่งDBCC SHOW_STATISTICS ('Sales.SalesOrderDetail', 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID'):

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

ความหนาแน่นของ SalesOrderID (ที่ฉันเข้าร่วม) คือ 3.178134E-05 นั่นหมายความว่า 1 / 3.178134E-05 (31465) เท่ากับจำนวนค่า SalesOrderID ที่ไม่ซ้ำกันในตาราง SalesOrderDetail

หากมี SalesOrderID ที่ไม่ซ้ำกัน 31465 รายการใน SalesOrderDetail จากนั้นด้วยการแจกแจงแบบสม่ำเสมอจำนวนแถวเฉลี่ยต่อ SalesOrderID คือ 121317 (จำนวนแถวทั้งหมด) หารด้วย 31465 ค่าเฉลี่ยคือ 3.85561

ดังนั้นถ้าจำนวนแถวที่จะวนซ้ำโดยประมาณคือ 2.61972 และค่าเฉลี่ยที่ส่งคืนใน 3.85561 ฉันจะคิดว่าจำนวนแถวโดยประมาณจะเป็น 2.61972 * 3.85561 = 10.10062

แต่จำนวนแถวโดยประมาณคือ 11.4867

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

คำตอบ:


20

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

การใช้ตัวประมาณค่าความน่าจะเป็นของ SQL Server 2012 การเลือกของการรวมจะทำให้จำนวนแถวโดยประมาณที่ด้านในของการรวมลูปซ้อนกันและไม่ใช่วิธีอื่น

จำนวน 11.4867 ได้มาจาก (สำหรับแสดงใน showplan) โดยการหาร cardinality โดยประมาณของเอาท์พุทการรวม (30.0919) ด้วยจำนวนการวนซ้ำ (2.61972) ผลที่ได้ใช้ความแม่นยำเดียวลอยเลขคณิตจุดเป็น11.4867

มันง่ายอย่างที่คิด โปรดทราบว่าตัวเลือกการรวม (แบบโลจิคัล) ไม่เกี่ยวข้องกับตัวเลือกของตัวดำเนินการรวมแบบฟิสิคัล มันจะยังคงเหมือนเดิมไม่ว่าการเข้าร่วมจะดำเนินการในท้ายที่สุดโดยใช้ Nested Loops, Hash หรือ Merge Join operator

ใน SQL Server 2012 และก่อนหน้านั้นการเลือกเข้าร่วม (โดยรวม) ถูกประเมินโดยใช้SalesOrderIDฮิสโตแกรมจากแต่ละตาราง (คำนวณสำหรับแต่ละขั้นตอนฮิสโตแกรมหลังจากการจัดตำแหน่งขอบเขตขั้นตอนโดยใช้การแก้ไขเชิงเส้นตามความจำเป็น) SalesOrderIDhistogram เกี่ยวข้องกับSalesOrderHeaderตารางนอกจากนี้ยังจะมีการปรับสำหรับผลการปรับขนาดของอิสระCustomerIDกรอง

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

ในฐานะที่เป็นด้านโน้ตของ SQL Server 2014 cardinality ประมาณการการใช้วิธีการที่แตกต่างกันเพื่อรวมข้อมูลอิสระกรองปรับ histogram ( "การจัดตำแหน่งหยาบ" ) ซึ่งผลในการประมาณการครั้งสุดท้ายที่แตกต่างกันของ10.1006แถวสำหรับการค้นหานี้:

Plan for computation:

  CSelCalcExpressionComparedToExpression
  (QCOL: [s].SalesOrderID x_cmpEq QCOL: [d].SalesOrderID)

Loaded histogram for column QCOL: [s].SalesOrderID from stats with id 1
Loaded histogram for column QCOL: [d].SalesOrderID from stats with id 1

Stats collection generated: 

  CStCollJoin(ID=4, **CARD=10.1006** x_jtInner)
      CStCollFilter(ID=3, CARD=2.61972)
          CStCollBaseTable(ID=1, CARD=31465 TBL: Sales.SalesOrderHeader AS TBL: s)
      CStCollBaseTable(ID=2, CARD=121317 TBL: Sales.SalesOrderDetail AS TBL: d)

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

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