รับตัวอย่างถัดไป:
IF OBJECT_ID('dbo.my_table') IS NOT NULL
DROP TABLE [dbo].[my_table];
GO
CREATE TABLE [dbo].[my_table]
(
[id] int IDENTITY (1,1) NOT NULL PRIMARY KEY,
[foo] int NULL,
[bar] int NULL,
[nki] int NOT NULL
);
GO
/* Insert some random data */
INSERT INTO [dbo].[my_table] (foo, bar, nki)
SELECT TOP (100000)
ABS(CHECKSUM(NewId())) % 14,
ABS(CHECKSUM(NewId())) % 20,
n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
FROM
sys.all_objects AS s1
CROSS JOIN
sys.all_objects AS s2
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_my_table]
ON [dbo].[my_table] ([nki] ASC);
GO
ถ้าฉันดึงระเบียนทั้งหมดที่เรียงลำดับโดย[nki]
(ดัชนีที่ไม่ใช่คลัสเตอร์):
SET STATISTICS TIME ON;
SELECT id, foo, bar, nki FROM my_table ORDER BY nki;
SET STATISTICS TIME OFF;
SQL Server Execution Times: CPU time = 266 ms, elapsed time = 493 ms
เครื่องมือเพิ่มประสิทธิภาพเลือกดัชนีคลัสเตอร์จากนั้นใช้อัลกอริทึมการเรียงลำดับ
แต่ถ้าฉันบังคับให้ใช้ดัชนีที่ไม่ใช่คลัสเตอร์:
SET STATISTICS TIME ON;
SELECT id, foo, bar, nki FROM my_table WITH(INDEX(IX_my_TABLE));
SET STATISTICS TIME OFF;
SQL Server Execution Times: CPU time = 311 ms, elapsed time = 188 ms
จากนั้นจะใช้ดัชนีที่ไม่คลัสเตอร์กับการค้นหาคีย์:
เห็นได้ชัดว่าหากดัชนีที่ไม่ใช่คลัสเตอร์ถูกเปลี่ยนเป็นดัชนีครอบคลุม:
CREATE UNIQUE NONCLUSTERED INDEX [IX_my_table]
ON [dbo].[my_table] ([nki] ASC)
INCLUDE (id, foo, bar);
GO
จากนั้นจะใช้เฉพาะดัชนีนี้:
SET STATISTICS TIME ON;
SELECT id, foo, bar, nki FROM my_table ORDER BY nki;
SET STATISTICS TIME OFF;
SQL Server Execution Times: CPU time = 32 ms, elapsed time = 106 ms
คำถาม
- เหตุใด SQL Server จึงใช้ดัชนีคลัสเตอร์รวมถึงอัลกอริทึมการเรียงลำดับแทนที่จะใช้ดัชนีที่ไม่ใช่คลัสเตอร์แม้ว่าเวลาดำเนินการจะเร็วขึ้น 38% ในกรณีหลัง