เหตุใด SQL Server จึงไม่ทำสถิติฮิสโตแกรมคอลัมน์ผสม


10

SQL Server มีสิ่งที่เรียกว่า "สถิติหลายคอลัมน์" แต่ไม่ใช่สิ่งที่คิดว่าจะหมายถึง

ลองดูตารางตัวอย่างต่อไปนี้:

CREATE TABLE BadStatistics 
(
    IsArchived BIT NOT NULL,
    Id INT NOT NULL IDENTITY PRIMARY KEY,
    Mystery VARCHAR(200) NOT NULL
);

CREATE NONCLUSTERED INDEX BadIndex 
    ON BadStatistics (IsArchived, Mystery);

ด้วยเหตุนี้จึงมีการสร้างสถิติสองรายการในดัชนีสองรายการที่เรามี:

สถิติสำหรับ BadIndex:

+--------------+----------------+-------------------------+
| All density  | Average Length | Columns                 |
+--------------+----------------+-------------------------+
| 0.5          | 1              | IsArchived              |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 37             | IsArchived, Mystery     |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 41             | IsArchived, Mystery, Id |
+--------------+----------------+-------------------------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0            | 0          | 24398   | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 216602  | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

สถิติสำหรับดัชนีคลัสเตอร์:

+--------------+----------------+---------+
| All density  | Average Length | Columns |
+--------------+----------------+---------+
| 4.149378E-06 | 4              | Id      |
+--------------+----------------+---------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 240999       | 240997     | 1       | 240997              | 1              |
+--------------+------------+---------+---------------------+----------------+
| 241000       | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

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

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

โปรดทราบว่าคำถามนี้ไม่ได้หมายถึงฮิสโตแกรมหลายมิติซึ่งเป็นสัตว์ที่แตกต่างอย่างสิ้นเชิง มันเกี่ยวกับฮิสโทแกรมมิติเดียวโดยมีมิติเดียวคือสิ่งอันดับที่มีหลายคอลัมน์

คำตอบ:


8

พื้นหลัง

SQL Server รุ่นปัจจุบันใช้ฮิสโตแกรมคอลัมน์เดี่ยวและข้อมูลความหนาแน่นหลายคอลัมน์เท่านั้น histograms คอลัมน์เดียวที่ใช้ในการประเมินการคัดสรรสำหรับภาคที่เหมาะสมเช่นหรือa = 1 b > 50แบบสอบถามที่มีหลายภาคส่วนจะรวมการเลือกเฉพาะบุคคล (พร้อมข้อสมมติฐาน) เพื่อสร้างการเลือกโดยรวมโดยประมาณ

สำหรับตัวอย่างดูบทความของฉันการประมาณเชิงสถิติ: การรวมสถิติความหนาแน่น

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

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

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

ฮิสโตแกรมหลายคอลัมน์

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

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

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

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

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

ทั้งหมดนี้เพิ่มขนาดความซับซ้อนและค่าใช้จ่ายในการบำรุงรักษา

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

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

เชิงอรรถ

ในกรณีนี้มันทำให้ทั้งฮิสโตแกรมมีประโยชน์น้อยกว่ามากเพราะคอลัมน์แรกมีค่าเพียงสองค่าเท่านั้น

ค่าแสงยังคงให้ข้อมูลที่เป็นประโยชน์เกี่ยวกับการกระจายของค่าในคอลัมน์ชั้นนำ: เมื่อสถิติที่ถูกสร้างขึ้นมี 24,398 แถวที่IsArchivedเป็นเท็จและ 216,602 แถวที่เป็นเป็นจริง

นอกจากนี้วัตถุสถิติบอกเราว่ามี (1 / 0.5) = 2 ค่าที่แตกต่างสำหรับIsArchived, (1 / 4.149378E-06) ~ = 241000 ค่าที่แตกต่างสำหรับที่(IsArchived, Mystery)มีขนาดแถวเฉลี่ย 37 ไบต์และมีความถี่เดียวกันสำหรับ(IsArchived, Mystery, Id)ด้วย 4 ไบต์พิเศษต่อแถว

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

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