ลองโยนหนึ่งล้านแถวไปยังตารางชั่วคราวพร้อมกับคอลัมน์สองสาม:
CREATE TABLE #174860 (
PK INT NOT NULL,
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (PK)
);
INSERT INTO #174860 WITH (TABLOCK)
SELECT RN
, RN % 1000
, RN % 10000
FROM
(
SELECT TOP 1000000 ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) RN
FROM master..spt_values v1,
master..spt_values v2
) t;
CREATE INDEX IX_174860_IX ON #174860 (COL1) INCLUDE (COL2);
ที่นี่ฉันมีดัชนีคลัสเตอร์ (โดยค่าเริ่มต้น) ในPK
คอลัมน์ มีดัชนีที่ไม่เป็นคลัสเตอร์COL1
ซึ่งมีคอลัมน์สำคัญCOL1
และรวมCOL2
อยู่ด้วย
พิจารณาคำถามต่อไปนี้:
SELECT *
FROM #174860
WHERE PK >= 15000 AND PK < 15005
AND COL2 = 5000;
ที่นี่ฉันไม่ได้ใช้BETWEEN
เพราะ Aaron Bertrand แขวนอยู่กับคำถามนี้
เครื่องมือเพิ่มประสิทธิภาพเซิร์ฟเวอร์ SQL ควรถามคำถามนั้นอย่างไร ฉันรู้ว่าตัวกรองบนPK
จะลดผลลัพธ์ที่ตั้งค่าเป็นห้าแถว เซิร์ฟเวอร์ SQL สามารถใช้ดัชนีคลัสเตอร์เพื่อข้ามไปยังห้าแถวเหล่านั้นแทนที่จะอ่านผ่านแถวทั้งหมดล้านแถวในตาราง อย่างไรก็ตามดัชนีคลัสเตอร์มีคอลัมน์ PK เป็นคอลัมน์สำคัญเท่านั้น COL2
เมื่อแถวที่ถูกอ่านในหน่วยความจำที่เราจำเป็นต้องใช้ตัวกรองบน ที่นี่PK
คือการค้นหาคำกริยาและCOL2
เป็นคำกริยา
เซิร์ฟเวอร์ SQL ค้นหาห้าแถวโดยใช้การค้นหาคำกริยาและลดห้าแถวเหล่านั้นเป็นหนึ่งแถวด้วยเพรดิเคตปกติ
ถ้าฉันกำหนดดัชนีคลัสเตอร์แตกต่างกัน:
CREATE TABLE #174860 (
PK INT NOT NULL,
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (COL2, PK)
);
และเรียกใช้แบบสอบถามเดียวกันฉันได้รับผลลัพธ์ที่แตกต่าง:
ในกรณีนี้ SQL Server สามารถค้นหาการใช้ทั้งสองคอลัมน์ในWHERE
ข้อ อ่านหนึ่งแถวจากตารางโดยใช้คอลัมน์สำคัญ
สำหรับอีกตัวอย่างหนึ่งให้พิจารณาคำถามนี้:
SELECT *
FROM #174860
WHERE COL1 = 500
AND COL2 = 3545;
ดัชนี IX_174860_IX เป็นดัชนีที่ครอบคลุมเนื่องจากมีคอลัมน์ทั้งหมดที่จำเป็นสำหรับการสืบค้น อย่างไรก็ตามมีเพียงCOL1
คอลัมน์สำคัญ SQL Server สามารถค้นหาด้วยคอลัมน์นั้นเพื่อค้นหา 1,000 แถวด้วยCOL1
ค่าที่ตรงกัน สามารถกรองแถวเหล่านั้นลงในCOL2
คอลัมน์เพิ่มเติมเพื่อลดผลลัพธ์สุดท้ายที่กำหนดเป็น 0 แถว