공부/데이터베이스

BookMark LoopUp

원클릭쓰리버그 2022. 3. 14. 20:47
728x90
USE Northwind;

-- 북마크 룩업
-- Index Scan vs Index Seek
-- Index Scan이 항상 나쁜 것은 아니고
-- Index Seek가 항상 좋은 것은 아니다.
-- 인덱스를 활용하는데 어떻게 느릴 수 있을까?

--NonClustered
--Clustered
--Heap Table

-- Clustered의 경우 Index Seek가 느릴 수가 없다.
-- NonClustered의 경우, 데이터가 Leaf Page에 없다.
-- 따라서 한 번 더 타고 가야함
	-- 1) RID -> Heap Table (Bookmark Lookup)
	-- 2) Key -> Clustered


SELECT*
INTO TestOrders
FROM Orders;

SELECT*
FROM TestOrders;

CREATE NONCLUSTERED INDEX Orders_Index01
ON TestOrders(CustomerID);

-- 인덱스 번호
SELECT index_id, name
FROM sys.indexes
WHERE object_id = object_id('TestOrders');

-- 조회
DBCC IND('Northwind', 'TestOrders',2);

SET STATISTICS TIME ON;
SET STATISTICS IO ON;
SET STATISTICS PROFILE ON;

-- 논리적 읽기 20
SELECT *
FROM TestOrders
WHERE CustomerID = 'QUICK';


-- 논리적 읽기 30
SELECT*
FROM TestOrders WITH(INDEX(Orders_Index01))
WHERE CustomerID = 'QUICK';

--> 무조건 INDEX를 이용해 찾는게 빠른건 아니다.

-- 논리적 읽기 30
SELECT*
FROM TestOrders WITH(INDEX(Orders_Index01))
WHERE CustomerID = 'QUICK' AND ShipVia = 3;
--> 정렬은 Orders_Index01의 CustomerID로 되어 있기 때문에 , 해당되는 30개를 Heap Table에서 하나하나 읽어
--	ShipVia가 3인 것을 비교하여 추출하였다. 

DROP INDEX TestOrders.Orders_Index01;

-- CASE 01
CREATE NONCLUSTERED INDEX Orders_Index01
ON TestOrders(CustomerID, ShipVia);

-- 논리적 읽기 10
SELECT*
FROM TestOrders WITH(INDEX(Orders_Index01))
WHERE CustomerID = 'QUICK' AND ShipVia = 3;
--> 정렬의 기준이 2개이므로 HeapTable에서 접근하지 않고 데이터 읽기가 가능하다.

-- Q) 그럼 조건 1 AND 조건2 필요하면, 무조건 INDEX(조건1, 조건2) 하는게 효율적인가?
-- A) no! 꼭 그렇지는 않다. DML(Insert, Update, Delete) 작업 부하가 증가하게 됩니다.

DROP INDEX TestOrders.Orders_Index01;

-- CASE 02
-- 논리적 읽기 10
CREATE NONCLUSTERED INDEX Orders_Index01
ON TestOrders(CustomerID) INCLUDE (Shipvia);
--> NonClustered에 Shipvia를 넣어 참고하게 한다. 그렇게 하여 Heap Table에 RID와 Shipvia 값을 참고하여 다이렉트로 접근한다.
SELECT*
FROM TestOrders WITH(INDEX(Orders_Index01))
WHERE CustomerID = 'QUICK' AND ShipVia = 3;


-- 위와 같은 노력에도 답이 없다면
-- Clustered Index 활용을 고려할 수 없다.
-- 단 Clustered Index는 테이블당 1개만 사용 가능.


-- 결론

-- NonClustered Index가 악영향을 주는 경우?
	-- 북마크 룩업이 심각한 부하를 야기할 수 있다.

-- 대안?
	-- 옵션 1) Covered Index (검색할 모든 컬럼을 포함하겠다.)
	-- 옵션 2) Index에다가 Include로 힌트를 남긴다.
	-- 옵션 3) Clustered 고려 (1개만 사용 가능) -> NonClustered 악영향을 줄 수 있음.

'공부 > 데이터베이스' 카테고리의 다른 글

Sorting  (0) 2022.03.24
JOIN의 원리  (0) 2022.03.21
INDEX SCAN vs INDEX SEEK  (0) 2022.03.14
Clustered VS Non-Clustered  (0) 2022.03.11
데이터베이스 세부 인덱스 확인 및 복합 인덱스  (0) 2022.03.09