속도를 높이기 위해 인덱스를 실험하고 있었지만 조인의 경우 인덱스가 쿼리 실행 시간을 개선하지 않고 경우에 따라 속도가 느려집니다.
테스트 테이블을 작성하고 데이터로 채우는 조회는 다음과 같습니다.
CREATE TABLE [dbo].[IndexTestTable](
[id] [int] IDENTITY(1,1) PRIMARY KEY,
[Name] [nvarchar](20) NULL,
[val1] [bigint] NULL,
[val2] [bigint] NULL)
DECLARE @counter INT;
SET @counter = 1;
WHILE @counter < 500000
BEGIN
INSERT INTO IndexTestTable
(
-- id -- this column value is auto-generated
NAME,
val1,
val2
)
VALUES
(
'Name' + CAST((@counter % 100) AS NVARCHAR),
RAND() * 10000,
RAND() * 20000
);
SET @counter = @counter + 1;
END
-- Index in question
CREATE NONCLUSTERED INDEX [IndexA] ON [dbo].[IndexTestTable]
(
[Name] ASC
)
INCLUDE ( [id],
[val1],
[val2])
이제 쿼리 1이 개선되었습니다 (약간만 개선되었지만 일관성이 있음).
SELECT *
FROM IndexTestTable I1
JOIN IndexTestTable I2
ON I1.ID = I2.ID
WHERE I1.Name = 'Name1'
인덱스가없는 통계 및 실행 계획 (이 경우 테이블은 기본 클러스터형 인덱스를 사용함) :
(5000 row(s) affected)
Table 'IndexTestTable'. Scan count 2, logical reads 5580, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 109 ms, elapsed time = 294 ms.
이제 색인이 활성화 된 상태 :
(5000 row(s) affected)
Table 'IndexTestTable'. Scan count 2, logical reads 2819, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 94 ms, elapsed time = 231 ms.
이제 인덱스로 인해 속도가 느려지는 쿼리 (테스트는 테스트 용으로 만 생성되므로 의미가 없음) :
SELECT I1.Name,
SUM(I1.val1),
SUM(I1.val2),
MIN(I2.Name),
SUM(I2.val1),
SUM(I2.val2)
FROM IndexTestTable I1
JOIN IndexTestTable I2
ON I1.Name = I2.Name
WHERE
I2.Name = 'Name1'
GROUP BY
I1.Name
클러스터형 인덱스가 활성화 된 경우 :
(1 row(s) affected)
Table 'IndexTestTable'. Scan count 4, logical reads 60, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 155106, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 17207 ms, elapsed time = 17337 ms.
이제 색인이 비활성화 된 상태 :
(1 row(s) affected)
Table 'IndexTestTable'. Scan count 5, logical reads 8642, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 2, logical reads 165212, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 17691 ms, elapsed time = 9073 ms.
질문은 :
- 인덱스가 SQL Server에서 제안되었지만 왜 상당한 차이로 인해 속도가 느려 집니까?
- 대부분의 시간이 걸리는 Nested Loop 조인은 무엇이며 실행 시간을 개선하는 방법은 무엇입니까?
- 내가 잘못하고 있거나 놓친 것이 있습니까?
- 기본 인덱스 (기본 키만 해당)를 사용하면 결합 테이블의 각 행에 대해 시간이 덜 걸리고 클러스터되지 않은 인덱스가있는 경우 결합이 행의 이름 열에 있기 때문에 결합 된 테이블 행을 더 빨리 찾을 수 있습니다. 색인이 작성되었습니다. 이는 쿼리 실행 계획에 반영되며 IndexA가 활성화 된 경우 Index Seek 비용이 적지 만 왜 여전히 느려 집니까? 또한 Nested Loop 왼쪽 외부 조인에서 속도 저하를 일으키는 원인은 무엇입니까?
SQL Server 2012 사용