본문 바로가기
MS-SQL

북마크 룩업

by kcj3054 2022. 4. 5.

북마크 룩업

  • 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