รีมัสบอกว่ามันขึ้นอยู่กับภาระงานของคุณ
ฉันต้องการพูดถึงเรื่องที่ทำให้เข้าใจผิดของคำตอบที่ยอมรับ
สำหรับแบบสอบถามที่ดำเนินการค้นหาความเท่าเทียมกันในคอลัมน์ทั้งหมดในดัชนีไม่มีความแตกต่างที่สำคัญ
ด้านล่างสร้างสองตารางและเติมข้อมูลที่เหมือนกัน ข้อแตกต่างเพียงอย่างเดียวคือปุ่มหนึ่งมีการเรียงลำดับจากมากไปน้อยให้เลือกและอีกอันหนึ่งมีปุ่มย้อนกลับ
CREATE TABLE Table1(MostSelective char(800), SecondMost TINYINT, Least CHAR(1), Filler CHAR(4000) null);
CREATE TABLE Table2(MostSelective char(800), SecondMost TINYINT, Least CHAR(1), Filler CHAR(4000) null);
CREATE NONCLUSTERED INDEX MyINDX on Table1(MostSelective,SecondMost,Least);
CREATE NONCLUSTERED INDEX MyINDX2 on Table2(Least,SecondMost,MostSelective);
INSERT INTO Table1 (MostSelective, SecondMost, Least)
output inserted.* into Table2
SELECT TOP 26 REPLICATE(CHAR(number + 65),800), number/5, '~'
FROM master..spt_values
WHERE type = 'P' AND number >= 0
ORDER BY number;
ตอนนี้ทำแบบสอบถามกับทั้งสองตาราง ...
SELECT *
FROM Table1
WHERE MostSelective = REPLICATE('P', 800)
AND SecondMost = 3
AND Least = '~';
SELECT *
FROM Table2
WHERE MostSelective = REPLICATE('P', 800)
AND SecondMost = 3
AND Least = '~';
... ทั้งคู่ใช้การปรับดัชนีและทั้งสองจะได้รับค่าใช้จ่ายเท่ากัน
ASCII art ในคำตอบที่ยอมรับนั้นไม่ได้มีความเป็นจริงว่าดัชนีนั้นมีโครงสร้างอย่างไร หน้าดัชนีสำหรับ Table1 แสดงไว้ด้านล่าง (คลิกที่ภาพเพื่อเปิดขนาดเต็ม)
หน้าดัชนีประกอบด้วยแถวที่มีคีย์ทั้งหมด (ในกรณีนี้มีคอลัมน์คีย์เพิ่มเติมต่อท้ายตัวระบุแถวเนื่องจากดัชนีไม่ได้ประกาศว่าไม่ซ้ำกัน แต่สามารถละเว้นข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ที่นี่ )
สำหรับแบบสอบถามด้านบน SQL Server ไม่สนใจเกี่ยวกับการเลือกคอลัมน์ มันไม่ค้นหาไบนารีของหน้ารากและค้นพบว่าที่สำคัญ (PPP...,3,~ )
คือ>=(JJJ...,1,~ )
และดังนั้นจึงควรอ่านหน้า< (SSS...,3,~ )
1:118
จากนั้นจะทำการค้นหาแบบไบนารีของรายการคีย์บนหน้านั้นและหาตำแหน่งของเพจแบบ leaf เพื่อเลื่อนลงไป
การเปลี่ยนแปลงดัชนีตามลำดับการเลือกไม่มีผลต่อจำนวนการเปรียบเทียบคีย์ที่คาดหวังจากการค้นหาแบบไบนารีหรือจำนวนหน้าที่ต้องสำรวจเพื่อทำดัชนีการค้นหา ที่ดีที่สุดมันอาจเร่งความเร็วการเปรียบเทียบคีย์เอง
บางครั้งการเรียงลำดับดัชนีที่เลือกมากที่สุดก่อนจะเหมาะสมสำหรับคิวรีอื่นในเวิร์กโหลดของคุณ
เช่นถ้าปริมาณงานมีแบบสอบถามของทั้งสองแบบฟอร์มต่อไปนี้
SELECT * ... WHERE MostSelective = 'P'
SELECT * ...WHERE Least = '~'
ดัชนีข้างต้นไม่ครอบคลุมดัชนีใดดัชนีหนึ่ง MostSelective
มีความสามารถเพียงพอที่จะทำแผนด้วยการค้นหาและการค้นหาที่คุ้มค่า แต่การค้นหาLeast
ไม่ใช่
อย่างไรก็ตามสถานการณ์นี้ (ไม่ครอบคลุมดัชนีการค้นหาในส่วนย่อยของคอลัมน์นำของดัชนีคอมโพสิต) เป็นเพียงหนึ่งระดับของการสืบค้นที่เป็นไปได้ที่สามารถช่วยได้โดยดัชนี หากคุณไม่เคยค้นหาด้วยMostSelective
ตัวเองหรือรวมกันMostSelective, SecondMost
และค้นหาด้วยการรวมกันของทั้งสามคอลัมน์แล้วความได้เปรียบเชิงทฤษฎีนี้ไม่มีประโยชน์กับคุณ
ข้อความค้นหาตรงกันข้ามเช่น
SELECT MostSelective,
SecondMost,
Least
FROM Table2
WHERE Least = '~'
ORDER BY SecondMost,
MostSelective
จะได้รับความช่วยเหลือโดยมีลำดับย้อนกลับของรายการที่กำหนดโดยทั่วไป - เนื่องจากครอบคลุมแบบสอบถามสามารถรองรับการค้นหาและส่งคืนแถวในลำดับที่ต้องการในการบูต
ดังนั้นนี่เป็นคำแนะนำซ้ำ ๆ บ่อยๆ แต่ที่จริงแล้วมันเป็นฮิวริสติกเกี่ยวกับประโยชน์ที่อาจเกิดขึ้นกับข้อความค้นหาอื่น ๆ - และมันไม่สามารถทดแทนการมองภาระงานของคุณได้