🔥 1. Northwind 데이터베이스 사용

이전 시간과 마찬가지로 Northwind Database를 사용한다.
📌 Northwind Database 다운로드 및 설정
🔗 Northwind GitHub Repository

현재 데이터베이스 정보 확인

-- 데이터베이스 정보 확인
EXEC sp_helpdb 'Northwind';

Northwind의 테이블 목록 확인

SELECT * FROM sys.tables;

🔥 2. 복합 인덱스란?

📌 복합 인덱스(Composite Index) 개념

  • 두 개 이상의 컬럼을 하나의 인덱스로 묶어 검색 최적화
  • 예: (OrderID, ProductID)를 인덱스로 설정하면 두 컬럼을 동시에 검색할 때 유리
  • 순서가 중요하다!첫 번째 컬럼을 기반으로 정렬됨

📌 복합 인덱스의 장점
다중 컬럼 검색 속도 향상
첫 번째 컬럼만 검색해도 인덱스 적용 가능

📌 복합 인덱스의 단점
두 번째 컬럼만 검색하면 인덱스가 무용지물
데이터 변경이 많으면 인덱스 유지 비용 증가


🔥 3. 복합 인덱스 실습 (Order Details 테이블 활용)

📌 3.1 주문 상세 정보 테이블 복사

기존 데이터 복사

-- 주문 상세 정보 테이블을 복사하여 테스트용 테이블 생성
SELECT * 
INTO TestOrderDetails
FROM [Order Details];

-- 데이터 확인
SELECT * FROM TestOrderDetails;

📌 3.2 복합 인덱스 생성

OrderID + ProductID 복합 인덱스 생성

CREATE INDEX Index_TestOrderDetails
ON TestOrderDetails(OrderID, ProductID);

생성된 인덱스 확인

EXEC sp_helpindex 'TestOrderDetails';

🔹 출력 예시

Index_Name               Index_Description
---------------------------------------------------
PK_TestOrderDetails      clustered, unique, primary key
Index_TestOrderDetails   nonclustered located on PRIMARY

📌 3.3 복합 인덱스 적용 테스트

테스트 1: (OrderID, ProductID) 조건 검색

SELECT * FROM TestOrderDetails
WHERE OrderID = 10248 AND ProductID = 11;

테스트 2: (ProductID, OrderID) 순서 변경

SELECT * FROM TestOrderDetails
WHERE ProductID = 11 AND OrderID = 10248;

테스트 3: OrderID만 검색

SELECT * FROM TestOrderDetails
WHERE OrderID = 10248;

테스트 4: ProductID만 검색

SELECT * FROM TestOrderDetails
WHERE ProductID = 11;

📌 실행 계획 분석
🔹 테스트 1~3: Index Seek → GOOD
🔹 테스트 4: Index Scan → BAD

실행 계획을 확인하면 인덱스가 어떻게 적용되는지 알 수 있다.

SET STATISTICS IO ON;
SELECT * FROM TestOrderDetails WHERE ProductID = 11;
SET STATISTICS IO OFF;

🔥 4. 인덱스가 특정 검색 조건에서 작동하지 않는 이유

인덱스 구조 확인 (DBCC IND 사용)

DBCC IND('Northwind', 'TestOrderDetails', 2);

📌 트리 구조 예시

          [ Root: 992 ]
       /           \
  [936]           [960]
  /    \           /    \
[952]  [960]     [961]  [970]

특정 페이지의 데이터 조회

DBCC PAGE('Northwind', 1, 936, 3);

🔹 출력 결과

  • OrderID가 첫 번째 컬럼으로 정렬
  • ProductID는 OrderID 내에서만 정렬됨
  • 따라서 ProductID만 검색할 경우 인덱스를 활용할 수 없음

📌 결론
복합 인덱스는 첫 번째 컬럼을 기준으로 정렬됨
첫 번째 컬럼(OrderID)을 포함한 검색은 인덱스를 사용
두 번째 컬럼(ProductID)만 검색하면 인덱스가 적용되지 않음


🔥 5. 데이터 추가 시 인덱스 변화 분석

50개의 데이터 추가

DECLARE @i INT = 0;
WHILE @i < 50
BEGIN
    INSERT INTO TestOrderDetails
    VALUES (10248, 100 + @i, 10, 1, 0);
    SET @i = @i +1;
END;

변경된 인덱스 정보 확인

DBCC IND('Northwind', 'TestOrderDetails', 2);

📌 트리 구조 변경

          [ Root: 992 ]
       /           \
  [936]           [960]
  /    \           /    \
[952]  [993]     [961]  [970]

새로운 페이지(Page 993)가 추가됨

DBCC PAGE('Northwind', 1, 993, 3);

📌 결론
데이터 추가 시 페이지 분할(SPLIT) 발생
페이지가 가득 차면 새로운 페이지가 생성됨
인덱스 성능 유지 위해 페이지 크기(FILLFACTOR) 조정 필요


🔥 6. 인덱스 가공 테스트 (주의할 점!)

새로운 Employees 복사 테이블 생성

SELECT LastName
INTO TestEmployees
FROM Employees;

-- 인덱스 추가
CREATE INDEX Index_TestEmployees
ON TestEmployees(LastName);

Substring 사용 (Index Scan) → BAD

SELECT * FROM TestEmployees
WHERE SUBSTRING(LastName, 1, 2) = 'Bu';

📌 실행 계획 분석
Index Scan 발생 (비효율적)
📌 원인

  • SUBSTRING(LastName, 1, 2)LastName을 변형하여 SQL이 인덱스를 활용할 수 없음

LIKE 사용 (Index Seek) → GOOD

SELECT * FROM TestEmployees
WHERE LastName LIKE 'Bu%';

📌 Index Seek 발생 (효율적!)
SQL이 LIKE 'Bu%'를 인덱스 범위 검색으로 처리


profile
李家네_공부방

0개의 댓글