PostgreSQL 18: 11.7. 표현식 인덱스

PostgreSQL 18: 11.7. 표현식 인덱스 (Indexes on Expressions)

인덱스 컬럼은 꼭 테이블의 실제 컬럼일 필요 없어요. 함수나 스칼라 표현식으로 계산된 결과도 인덱스로 만들 수 있답니다. 이번 섹션에서는 표현식 인덱스의 개념, 활용 예시, 그리고 성능상 주의할 점을 함께 살펴볼게요.

출처: 공식문서

표현식 인덱스란?

일반적으로 인덱스는 테이블의 특정 컬럼에 만들어요. 그런데 PostgreSQL에서는 컬럼 하나만 인덱스로 쓰는 게 아니라, 컬럼 값을 가공한 함수나 표현식의 결과를 인덱스로 만들 수 있어요. 이렇게 하면 계산 결과를 기준으로 테이블에 빠르게 접근할 수 있답니다.

대소문자 구분 없는 비교 예시

대표적인 예로 대소문자를 구분하지 않는 비교를 들어볼게요. 보통 lower 함수를 사용해서 이런 비교를 하죠:

SELECT * FROM test1 WHERE lower(col1) = 'value';

이런 쿼리가 자주 실행된다면, lower(col1) 함수의 결과에 인덱스를 만들어 두면 좋아요:

CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));

여기서 잠깐! 이 인덱스를 UNIQUE로 선언하면 재미있는 효과가 있어요. col1 값이 대소문자만 다른 행도 중복으로 간주해서 생성을 막아준답니다. 물론 완전히 동일한 값도 막아주고요. 즉, 단순한 유니크 제약으로는 정의할 수 없는 제약 조건을 표현식 인덱스로 강제할 수 있어요.

문자열 결합 예시

또 다른 예시를 볼까요? 이름과 성을 합쳐서 검색하는 쿼리가 자주 있다고 해볼게요:

SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';

이런 경우에도 다음과 같이 표현식 인덱스를 만들면 도움이 돼요:

CREATE INDEX people_names ON people ((first_name || ' ' || last_name));

문법 주의사항

CREATE INDEX 명령에서 인덱스 표현식을 사용할 때는 두 번째 예시처럼 괄호를 꼭 써줘야 해요. 다만 표현식이 단순한 함수 호출 하나라면 첫 번째 예시처럼 괄호를 생략할 수 있답니다.

성능 고려사항

표현식 인덱스는 유지 비용이 상대적으로 비싸요. 행이 삽입되거나 HOT 업데이트가 아닌 업데이트가 발생할 때마다 파생된 표현식을 계산해야 하거든요. 하지만 인덱스 검색 중에는 표현식을 다시 계산하지 않아요. 이미 계산된 값이 인덱스에 저장되어 있기 때문이에요.

위의 두 예시 모두 시스템은 쿼리를 그냥 WHERE indexedcolumn = 'constant' 형태로 인식해요. 그래서 검색 속도는 다른 단순 인덱스 쿼리와 동일하답니다.

결론적으로, 표현식 인덱스는 삽입·업데이트 속도보다 검색 속도가 더 중요할 때 유용해요.

더 알아보기 (Learn more)