다음 예제를 보자.
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 % 더 빠르더라도 클러스터되지 않은 인덱스를 사용하는 대신 클러스터형 인덱스와 정렬 알고리즘을 사용하는 이유는 무엇입니까?