북마크 룩업
- NonClustered일 경우 북마크 룩업은 index seek를 한 뒤 RID값을 통해서 값을 찾는 행위를 말한다. 북마크 룩업으로 인해서 굉장히 성능 저하가 많이 발생할 수도 있다..
세팅
USE Northwind;
-- 인덱스 접근 방식
SELECT *
INTO TestOrders
FROM Orders
SELECT *
FROM TestOrders
CREATE NONCLUSTERED INDEX Orders_Index01
ON TestOrders(CustomerID)
-- 조회
DBCC IND('Northwind','TestOrders',2)
-- 1088
-- 1040 1056 1057
-- Heap Table[{Page} {Page} ... ]
SET STATISTICS TIME ON
SET STATISTICS IO ON
SET STATISTICS PROFILE ON
- 위에서 1088이 ROOT로 확인이 되었다.. 메시지에서 논리적 횟수랑 실행시간을 확인하기 위해서 STATISTICS를 추가하였습니다.
인덱스가 걸려있으면 무조건 인덱스를 사용가능가?
SELECT *
FROM TestOrders
WHERE CustomerID = 'QUICK'
- 위의 소스에서 CustomerID는 인덱스를 걸었지만 seek가 아닌 scan을한다 이유는 scan을 하는 경우가 더 빠를 수도 있기때문에 db내부에서 그렇게 한다.. lookup할 때 시간이 많이 걸리니?
강제로 인덱스 사용
SELECT *
FROM TestOrders WITH(INDEX(Orders_Index01))
WHERE CustomerID = 'QUICK'
- 강제로 인덱스를 사용하니 Lookup쪽에 시간이 많이 걸린다 이유는 인덱스인 CustomerID에서 QUICK이 28개가 존재해서 RID값을 가지고 HEAP Table에 가는 것을 28번 다 해야한다.
LookUP을 줄이는 방법
convered Index (사용할 컬럼들을 다 인덱스로 걸어주기)
- 사용할 칼럼들을 다 인덱스로 넣어주면된다.
CREATE NONCLUSTERED INDEX Orders_Index01
ON TestOrders(CustomerID, ShipVia)
- 해당 방법의 단점은 두가지 칼럼들을 다 인덱스로 걸어줬기때문에 DML (Delete, Update, Insert) 작업을 할때 계속해서 순서가 바뀌기 때문에 작업 부하가 증가하기때문이다.
부가적인 것을 INCLUDE로 묶기
SELECT *
FROM TestOrders WITH(INDEX(Orders_Index01))
WHERE CustomerID = 'QUICK' AND ShipVia = 3
여기서 convered Index 랑 비슷하다고 생각할 수 있지만 그렇지않다 이유는 convered는 정렬까지 되지만, 여기서 INCLUDE한 인덱스는 정렬은 되지않고 참고만 할 수 있는 것이다.
NonClustered가 아닌 Clustered로 만들기
이 방법이 가장 확실하지만 ClusteredIndex는 테이블당 하나만 적용할 수 있기때문에 신중을 기해야한다.
결론
- NONCLUSTERED INDEX가 악영향을 주는 이유는 -> 북마크 룩업이 심각한 부하를 야기할 경우이다.
- 루키스님의 db강의를 학습한 후 작성하였습니다.
'MS-SQL' 카테고리의 다른 글
Sorting (0) | 2022.04.06 |
---|---|
인덱스 칼럼순서 (0) | 2022.04.06 |
indexScan vs IndexSeek (0) | 2022.04.05 |
Clustered vs NonClustered (0) | 2022.04.05 |
복합인덱스 (0) | 2022.04.05 |