การประมาณค่าСardinalityของภาคที่ครอบคลุมบางส่วน


13

ในขณะนี้ฉันกำลังพยายามหาวิธีที่ SQL Server จะประเมินความสำคัญของช่วงของเพรดิเคตที่ครอบคลุมขั้นตอนฮิสโตแกรมบางส่วน

บนอินเทอร์เน็ตด้วยความคิดเชิงสถิติสำหรับการคำนวณแบบตามลำดับขั้นและสถิติที่มีค่าฉันพบคำถามที่คล้ายกันและ Paul White ให้คำตอบที่น่าสนใจ

ตามคำตอบของ Paul สูตรการประมาณค่า cardinality สำหรับ predicates> = และ> (ในกรณีนี้ฉันสนใจเฉพาะรุ่นตัวประมาณ Cardinality อย่างน้อย 120) ดังนี้:

สำหรับ>:

Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))

สำหรับ> =:

Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))

ฉันทดสอบแอปพลิเคชันของสูตรเหล่านี้ในตาราง[การผลิต]. [TransactionHistory]ตารางของฐานข้อมูลAdventureWorks2014ตามกริยาช่วงโดยใช้คอลัมน์TransactionDateและช่วงวันที่และเวลาระหว่าง '20140614' และ '20140618'

สถิติสำหรับขั้นตอนฮิสโตแกรมของช่วงนี้มีดังนี้:

histogram

ตามสูตรฉันคำนวณ cardinality สำหรับข้อความค้นหาต่อไปนี้:

SELECT COUNT(1)
FROM [AdventureWorks2014].[Production].[TransactionHistory]
WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000'

การคำนวณดำเนินการโดยใช้รหัสต่อไปนี้:

  DECLARE @predStart DATETIME =  '20140615 00:00:00.000'
  DECLARE @predEnd DATETIME = '20140616 00:00:00.000'

  DECLARE @stepStart DATETIME = '20140614 00:00:00.000'
  DECLARE @stepEnd DATETIME = '20140618 00:00:00.000'

  DECLARE @predRange FLOAT = DATEDIFF(ms, @predStart, @predEnd)
  DECLARE @stepRange FLOAT = DATEDIFF(ms, @stepStart, @stepEnd)

  DECLARE @F FLOAT = @predRange / @stepRange;

  DECLARE @avg_range_rows FLOAT = 100.3333
  DECLARE @distinct_range_rows INT = 3
  DECLARE @EQ_ROWS INT = 0

  SELECT @F AS 'F'

  --for new cardinality estimator

  SELECT @EQ_ROWS + @avg_range_rows * (@F * (@distinct_range_rows - 1) + 1) AS [new_card]

หลังจากคำนวณฉันได้ผลลัพธ์ดังนี้

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

ตามสูตรปรากฎเป็น 150.5 แต่เครื่องมือเพิ่มประสิทธิภาพประมาณการส่วนที่ 225.75 แถวและถ้าคุณเปลี่ยนขอบบนของภาคแสดงเป็น '20140617' เครื่องมือเพิ่มประสิทธิภาพจะประเมินแถวที่ 250.833 แล้วในขณะที่ใช้สูตรที่เราได้รับเท่านั้น 200.6666 แถว

โปรดบอกฉันว่า Cardinality Estimator ประเมินในกรณีนี้ได้อย่างไรฉันอาจทำผิดพลาดที่ไหนสักแห่งในการทำความเข้าใจสูตรที่ยกมา?


Sql server 2014 12.0.5 SP2
ПавелКовалёв

คำตอบ:


12

SQL Server ใช้การคำนวณที่แตกต่างกันในสถานการณ์ที่แตกต่างกัน ตัวอย่างของคุณแตกต่างจากคำถาม & การเชื่อมโยงเนื่องจากช่วงของคุณมีอยู่ทั้งหมดภายในขั้นตอนเดียว มันไม่ข้ามขอบเขตขั้นตอน นอกจากนี้ยังเป็นช่วงเวลาที่มีสองปลายมากกว่าหนึ่ง เขียนBETWEENเป็นเช่นเดียวกับการเขียนสองภาคแยกจากกันพร้อมและ>=<=

ช่วงเวลาที่มีสองขอบเขตภายในขั้นตอนเดียว

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

การใช้ขั้นตอนฮิสโตแกรมที่กำหนดในคำถาม:

ขั้นตอนฮิสโตแกรมของคำถาม

สำหรับแบบสอบถามด้วยBETWEEN '20140615' AND '20140616'การคำนวณคือ:

DECLARE
    @Q1 float = CONVERT(float, CONVERT(datetime, '2014-06-15')),
    @Q2 float = CONVERT(float, CONVERT(datetime, '2014-06-16')),
    @K1 float = CONVERT(float, CONVERT(datetime, '2014-06-14')),
    @K2 float = CONVERT(float, CONVERT(datetime, '2014-06-18')),
    @RANGE_ROWS float = 301,
    @DISTINCT_RANGE_ROWS float = 3;

DECLARE
    @S1 float = (@Q1 - @K1) / (@K2 - @K1),
    @S2 float = (@Q2 - @K1) / (@K2 - @K1);

DECLARE
    @F float = @S2 - @S1;

DECLARE
    @AVG_RANGE_ROWS float = @RANGE_ROWS / @DISTINCT_RANGE_ROWS;

SELECT
    @AVG_RANGE_ROWS * ((@F * (@DISTINCT_RANGE_ROWS - 2)) + 2);

... ให้225.75 การเปลี่ยน@Q2จาก'20140616'การ'20140617'ให้ผลของ250.833

ผลลัพธ์ทั้งคู่ตรงกับที่ระบุในคำถาม

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