SQL 캠프 광고 이미지
  • SQL

멀티 컬럼 인덱스

    Contents

SQL 캠프 광고 이미지
SQL 캠프 광고 이미지
 
보통 테이블의 한 컬럼에 인덱스를 건다고 생각하지만, 테이블의 두 컬럼 이상을 묶어서도 정의할 수 있습니다. 예를 들어 다음과 같은 형식의 테이블이 있다고 가정해 보겠습니다.
 
그리고 아래와 같은 쿼리를 자주 실행한다고 생각해 보겠습니다.
 
이런 경우 major 컬럼, minor 컬럼을 묶어 인덱스를 거는 것이 적절할 수 있습니다. (*역자주: 이런 상황에서는 무조건 멀티 컬럼 인덱스가 필요하다는 것이 아닙니다. 인덱스설계를 할 때에는 이외에도 여러가지 상황을 고려해야 합니다. 원문에서도 ‘적절합니다’라고 얘기하지 않고, ‘적절할 수 있습니다(might be appropriate)’라고 표기 되어있습니다.)
 
현재 B-tree, GiST, GIN, BRIN 인덱스 유형만 멀티 컬럼 인덱스를 지원합니다. 이 멀티 컬럼 인덱스에서 ‘멀티’라는 뜻은 인덱스 키를 여러개 가질 수 있다는 뜻으로, INCLUDE 컬럼의 여부와는 무관합니다. 인덱스에는 INCLUDE 컬럼을 포함하여 최대 32개의 컬럼이 포함될 수 있습니다. 이 제한을 변경하고 싶다면 pg_config_manual.h 파일을 참고하세요. (*역자주: 인덱스를 생성할 때, INCLUDE 옵션을 이용하여 ‘키’가 아닌 컬럼을 인덱스에 포함시킬 수 있습니다. 더 자세한 내용을 알고 싶다면 SQL Commands - CREATE INDEX 문서를 참고하세요.)
멀티 컬럼 B-Tree 인덱스는 인덱스의 모든 컬럼 하위 집합을 포함하는 쿼리 조건에 사용할 수 있지만, 가장 왼쪽에 있는 컬럼(리딩 컬럼)에 제약 조건이 있을 때 가장 효율적으로 동작합니다. 정확한 규칙은 리딩 컬럼의 일치(*역자주: =) 조건과, 불일치 조건(*역자주: >, < 등)이 등장하는 첫 번째 컬럼을 이용해 인덱스 스캔 범위를 좁히는 것인데요. 이를 제외한, 그러니까 멀티 컬럼 집합에서 상대적으로 오른쪽에 위치한 컬럼들은 인덱스의 스캔 범위를 좁혀주지는 못합니다. 예를 들어, (a, b, c) 멀티 컬럼 인덱스가 걸려있는 테이블에 WHERE a = 5 AND b >= 42 AND c < 77 필터링 조건을 가진 쿼리를 실행한다고 가정해 보겠습니다. a = 5, b = 42 에서 시작해 a = 5 에 해당하는 마지막 노드까지 인덱스가 스캔됩니다. 원칙적으로는 a 제약 조건이 없고 b 또는 c 에 제약 조건이 있는 쿼리에도 이 멀티 컬럼 인덱스를 사용할 수는 있지만, 전체 인덱스를 스캔해야 하기 때문에 대부분의 경우 플래너는 인덱스 사용보다 순차적으로 전체 테이블을 스캔하는 것을 선호할 것입니다.
 
각 컬럼은 인덱스 유형에 적합한 연산자와 함께 사용해야 합니다.
멀티 컬럼 인덱스는 자주 사용하지 않는 것이 좋습니다. 대부분의 상황에서 단일 컬럼에 대한 인덱스로 충분합니다. 공간과 시간을 절약할 수 있기 때문입니다. (*역자주: 종종 인덱스는 메모리에만 있는 것으로 오해하는 분들이 있는데, 인덱스를 저장하는 데에도 디스크 저장 공간이 필요합니다. 또한 UPDATE, INSERT, DELETE 등 테이블을 조작할 때 인덱스도 함께 업데이트를 해야하기 때문에 과도하게 인덱스를 사용하면 처리 속도가 느려집니다.) 컬럼이 3개 이상인 인덱스는 테이블의 사용법이 극도로 정형화되어 있지 않는 한 도움이 되지 않습니다. 인덱스 설정에 대해 더 자세하게 알고 싶다면 Section 11.5Section 11.9도 참고해 주세요.
 
 
✍🏻
Editor 선미’s comment
이 글의 원문은 PostgreSQL 공식문서 “Chapter 11. Indexes - 11.3. Multicolumn Indexes”입니다. PostgreSQL 버전 16을 기준으로 작성되었습니다.
이전 글과 마찬가지로 전문 번역을 하지 않고 자주 사용되는 B-Tree 인덱스 위주로 번역하였습니다. PostgreSQL에서 지원하는 모든 종류의 멀티 컬럼 인덱스에 대해 알고 싶은 분이라면 꼭 원문을 참고해주세요.
코멘트를 쓰는 김에 역자로서 수다를 좀 떨어보고 싶은데요. 영어로 인덱스는 생성(create) 또는 정의(define)하는 것인데, 가만히 생각해보니 한국말로는 ‘건다’라고 하더라구요. 번역을 하면서 ‘인덱스를 생성한다’, ‘인덱스를 정의한다’라고 하는 것보다 ‘인덱스를 건다’라고 적는게 좀 더 말 맛이 사는 것 같아 이번 글에서는 ‘건다’로도 표시해보았습니다. 실무 하시는 분들이 재밌게 읽으셨으면 합니다.
이 번역 작업이 여러분이 인덱스에 대해 공부하는데 도움이 되었으면 좋겠습니다. PostgreSQL 공식 문서가 인덱스에 대해 잘 쓰여져 있어 이전부터 번역을 꼭 해오고 싶었는데요. 흔쾌히 허가해주신 PostgreSQL CoC(Code of Conduct)팀 감사합니다. 이해를 돕기 위해 역자의 의역이 섞여있으니 만약 번역과 원문 간에 차이가 있는 경우 원문을 우선적으로 생각해주세요. 번역 오류는 contact@datarian.io로 제보해주세요.
PostgreSQLPostgreSQL 공식 문서

The World's Most Advanced Open Source Relational Database

함께 읽어보면 좋은 글

주식회사 데이터리안