Included Columns(SQL-server)

2025. 2. 21. 07:57· 백엔드
목차
  1. 1. Included Columns
  2. 1. Included Columns란?
  3. 2. Included Columns가 없는 비클러스터형 인덱스 예시
  4. 3. 포함된 컬럼을 사용하는 비클러스터형 인덱스 예시
  5. 4. 포함된 컬럼이 있는 경우와 없는 경우의 차이점
  6. 5. 포함된 컬럼을 사용할 때 고려해야 할 점
  7. 6. 포함된 컬럼이 필요한 경우와 불필요한 경우
  8. 📌 정리

1. Included Columns

mysql에서는 이 기능을 활용할 수 없다. DBMS의 한 종류인 SQL-server는 이 기능을 지원한다.

SQL-server를 통해서 Included Columns에 대해서 알아보자.

Included Columns는 개념적으로 배워야 할 가치가 있으므로 mysql에서 지원하지 않는다 하더라도 한 번 알아보자.

1. Included Columns란?

📌 비클러스터형 인덱스의 리프 노드에는 id만 존재했기 때문에 그 id를 찾아서 다시 클러스터형 인덱스를 순회(Clustered Index Lookup)해야 했었다.

하지만, 비 클러스터형 인덱스의 리프노드에 추가 컬럼을 포함시킨다면 2번 순회할 필요가 없을 것이다.

📌 포함된 컬럼은 오직 비클러스터형(Non-Clustered) 인덱스에서만 사용 가능하며, 클러스터형(Clustered) 인덱스에는 적용되지 않는다.(지극히 당연한 이야기)

📌 특정 컬럼을 비클러스터형 인덱스에 추가(Included)하면, 해당 컬럼의 데이터를 리프(Leaf) 레벨에 저장하여 클러스터형 인덱스를 다시 조회(Bookmark Lookup)하지 않고도 데이터를 바로 반환할 수 있다.

📌SQL Server에서는 인덱스 키와는 별개로 추가 컬럼을 리프 노드에 저장할 수 있다. 이 경우, 추가 컬럼들은 인덱스의 정렬 순서나 키 크기에 영향을 주지 않고, 단지 "커버링 인덱스(covering index)"로 활용되어, 쿼리 시 기본 테이블 접근을 줄여준다.

MySQL은 Included Columns 개념을 지원하지 않는다. SQL-server에서는 가능하다.

  • SQL Server의 Included Columns:
    SQL Server에서는 인덱스 키와는 별개로 추가 컬럼을 리프 노드에 저장할 수 있다.
  • MySQL의 복합 인덱스:
    MySQL에서는 별도의 INCLUDE 구문이 없기 때문에, 리프노드에 컬럼을 추가하기 위해서는 필요한 컬럼들을 인덱스 정의에 포함시켜야 한다. 하지만, 이렇게 생성된 복합 인덱스는 정의된 모든 컬럼이 인덱스 키의 일부가 되어 정렬 순서에 영향을 미친다.
    즉, 인덱스의 선두 컬럼은 검색 기준이 되고, 그 뒤의 컬럼들은 정렬에도 관여하게 된다.
    이 방식은 쿼리 커버링(즉, 인덱스만으로 쿼리 결과를 제공하는)을 가능하게 하지만, SQL Server의 Included Columns처럼 키 외부에 단순히 저장되는 형태는 아니다.

MySQL에서는 인덱스에 추가 컬럼을 포함하여 커버링 인덱스 효과를 얻을 수는 있으나, 이 방식은 인덱스 키에 영향을 주므로 SQL Server의 INCLUDE와는 구조적으로 차이가 있다.

2. Included Columns가 없는 비클러스터형 인덱스 예시

CREATE NONCLUSTERED INDEX idx_student_name ON Student(Name);

✅ 위 인덱스는 Name 컬럼만 인덱스로 설정하며, SELECT * FROM Student WHERE Name = 'Gary' 같은 쿼리를 최적화할 수 있음
✅ 하지만 SELECT ID, Name, BloodGroup FROM Student WHERE Name = 'Gary' 같은 쿼리에서 BloodGroup 컬럼이 필요하면, SQL Server는 추가적으로 클러스터형 인덱스를 조회해야 함 (Bookmark Lookup 발생)
✅ Bookmark Lookup이 많아지면 쿼리 성능이 저하될 가능성이 있음

3. 포함된 컬럼을 사용하는 비클러스터형 인덱스 예시

CREATE NONCLUSTERED INDEX idx_student_name_incl ON Student(Name) INCLUDE (BloodGroup);

✅ 위 인덱스는 Name을 인덱스로 유지하면서, BloodGroup 컬럼을 리프(Leaf) 레벨에 추가 저장
✅ SELECT ID, Name, BloodGroup FROM Student WHERE Name = 'Gary' 실행 시 클러스터형 인덱스를 조회하지 않고도 ID, Name, BloodGroup을 바로 반환 가능
✅ Bookmark Lookup을 방지하여 쿼리 성능 향상 가능

4. 포함된 컬럼이 있는 경우와 없는 경우의 차이점

구분 비클러스터형 인덱스만 있는 경우 포함된 컬럼이 추가된 경우
데이터 저장 위치 Name 컬럼만 저장 Name + BloodGroup 컬럼 포함
쿼리 실행 방식 SELECT ID, Name, BloodGroup FROM Student WHERE Name = 'Gary' 실행 시 클러스터형 인덱스 추가 조회 필요 (Bookmark Lookup 발생) 클러스터형 인덱스 조회 없이 즉시 결과 반환
성능 차이 Bookmark Lookup이 많아질수록 성능 저하 가능 쿼리 속도 향상 및 I/O 부담 감소

📌 포함된 컬럼을 활용하면 Bookmark Lookup을 줄일 수 있어 SELECT 성능을 향상시킬 수 있다.

5. 포함된 컬럼을 사용할 때 고려해야 할 점

✅ 업데이트(UPDATE) 및 삽입(INSERT) 성능 저하 가능

  • 만약 포함된 컬럼 BloodGroup의 값이 업데이트되면, 클러스터형 인덱스뿐만 아니라 비클러스터형 인덱스의 리프(Leaf) 페이지에도 동일한 업데이트가 반영되어야 한다.
  • 즉, 포함된 컬럼을 너무 많이 추가하면 업데이트 성능이 저하될 수 있음

✅ 비클러스터형 인덱스 크기 증가

  • 포함된 컬럼이 많아질수록 비클러스터형 인덱스 크기가 커지며, 저장 공간을 많이 차지할 수 있다.
  • 권장 사항: 포함된 컬럼은 4~5개 이내로 제한하는 것이 좋음

✅ 자주 사용하는 SELECT 쿼리에 맞춰 포함된 컬럼을 설정해야 함

  • 만약 SELECT Name, BloodGroup FROM Student WHERE Name = 'Gary' 쿼리가 자주 사용된다면, BloodGroup을 포함된 컬럼으로 추가하는 것이 효과적
  • 하지만 BloodGroup이 자주 변경되거나, SELECT 쿼리에서 거의 사용되지 않는다면 포함하는 것이 오히려 비효율적

📌 Microsoft 권장 사항: 너무 많은 컬럼을 포함하면 인덱스 크기가 커지고, 업데이트 및 삽입 성능이 저하될 수 있으므로, 4~5개 이하의 컬럼만 포함할 것을 권장

6. 포함된 컬럼이 필요한 경우와 불필요한 경우

포함된 컬럼이 필요한 경우 포함된 컬럼이 불필요한 경우
자주 사용하는 SELECT 쿼리에 특정 컬럼이 포함됨 해당 컬럼이 자주 업데이트됨
Bookmark Lookup이 많이 발생하여 성능 저하됨 해당 컬럼이 거의 사용되지 않음
자주 검색되는 컬럼이지만, 클러스터형 인덱스 조회를 피하고 싶음 비클러스터형 인덱스 크기가 너무 커짐

📌 정리

✔ 포함된 컬럼(Included Columns)은 오직 비클러스터형(Non-Clustered) 인덱스에서만 사용할 수 있음
✔ Bookmark Lookup을 줄여 SELECT 성능을 최적화할 수 있음
✔ 너무 많은 포함된 컬럼을 추가하면 인덱스 크기가 증가하고, UPDATE/INSERT 성능이 저하될 수 있음
✔ 자주 사용하는 SELECT 쿼리를 분석하여 필요한 경우에만 포함된 컬럼을 추가하는 것이 좋음
✔ Microsoft 권장 사항: 4~5개 이하의 컬럼만 포함하는 것이 좋음

이제 포함된 컬럼을 활용하여 SQL Server에서 인덱스 성능을 최적화할 수 있다.

'백엔드' 카테고리의 다른 글

JPA Entity(JPA 공식문서 정리 - 1)  (1) 2025.03.03
MySQL 쿼리 최적화: 테이블 스캔, 인덱스 스캔, 옵티마이저, 인덱스 힌트, EXPLAIN ANALYZE  (0) 2025.02.25
인덱스 조각화, 실행계획, 인덱스 scripts  (0) 2025.02.21
인덱스의 기초 - Page,Extent,Heap,Clustered Index(Sql-server)  (0) 2025.02.17
요구사항 명세서(SRS)  (2) 2025.01.06
  1. 1. Included Columns
  2. 1. Included Columns란?
  3. 2. Included Columns가 없는 비클러스터형 인덱스 예시
  4. 3. 포함된 컬럼을 사용하는 비클러스터형 인덱스 예시
  5. 4. 포함된 컬럼이 있는 경우와 없는 경우의 차이점
  6. 5. 포함된 컬럼을 사용할 때 고려해야 할 점
  7. 6. 포함된 컬럼이 필요한 경우와 불필요한 경우
  8. 📌 정리
'백엔드' 카테고리의 다른 글
  • JPA Entity(JPA 공식문서 정리 - 1)
  • MySQL 쿼리 최적화: 테이블 스캔, 인덱스 스캔, 옵티마이저, 인덱스 힌트, EXPLAIN ANALYZE
  • 인덱스 조각화, 실행계획, 인덱스 scripts
  • 인덱스의 기초 - Page,Extent,Heap,Clustered Index(Sql-server)
최현준 개발일기
최현준 개발일기
남이 이해하기 쉽도록 글을 쓰는 걸 좋아합니다. https://github.com/Hyeonjun0527
최현준 개발일기
최현준 개발일기
최현준 개발일기
전체
오늘
어제
  • 분류 전체보기 (30)
    • 프론트엔드 (0)
    • 알고리즘 (10)
    • 백엔드 (13)
      • 김영한 스프링 기본편 (4)
    • 분류하기 애매한 것들 (0)
    • ZERO-TO-ONE-프로젝트 (2)
    • 휴지통(추후 관리 및 삭제) (0)
      • JAVA (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • fill factor
  • 알고리즘
  • 엔티티 매니저 팩토리
  • DBMS
  • sql-server
  • 실행 계획
  • PS
  • 인덱스
  • 백준
  • JPA
  • included columns
  • MySQL
  • 인덱스 조각화

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
최현준 개발일기
Included Columns(SQL-server)
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.