PostgreSQL pg_trgm로 텍스트 검색 개선
pg_trgm 확장을 통해 PostgreSQL에서 유사 문자열 검색의 응답 속도와 정확도를 높이는 방법과 적용 사례, 성능 고려사항 모음
목차
소개
긴 텍스트나 사용자 입력을 대상으로 빠르고 유연한 검색이 필요할 때가 많다. PostgreSQL의 pg_trgm 확장은 이런 상황에서 유용하다. 이 글은 처음 접하는 사람도 이해하기 쉽도록 pg_trgm의 개념, 설치, 인덱스 적용, 쿼리 활용, 튜닝 포인트를 순서대로 설명한다. 또한 실제 쿼리 예시와 주의사항을 함께 제시한다.
pg_trgm이란
pg_trgm은 문자열을 트라이그램(trigram, 3-문자 단위 조각)으로 분해해 유사도를 계산하는 확장 모듈이다. 트라이그램 기반 검색은 오타가 있거나 일부만 일치하는 경우에도 높은 정확도로 매칭을 찾는다. 특히 부분 일치나 근사 문자열 검색에서 장점을 보인다.
왜 pg_trgm을 사용하는가
- 부분 일치와 유사도 기반 정렬이 쉬움
- GIN 또는 GiST 인덱스를 사용해 대용량 데이터에서도 빠른 검색 가능
- LIKE나 ILIKE보다 더 유연한 매칭 제공
설치 및 기본 사용법
pg_trgm은 PostgreSQL 확장으로 제공된다. 권한이 있으면 데이터베이스 단위로 확장을 설치한다. 설치 후 간단한 함수와 연산자를 사용할 수 있다.
확장 설치
CREATE EXTENSION IF NOT EXISTS pg_trgm;
간단한 유사도 조회
SELECT similarity('kitten', 'sitting');
-- 유사도 점수를 반환
인덱스 생성
pg_trgm은 GIN과 GiST 인덱스를 지원한다. 일반적으로 GIN(gin_trgm_ops)이 빠르다. 텍스트 컬럼에 인덱스를 추가하면 % 연산자나 similarity 기반 정렬에서 인덱스가 사용된다.
GIN 인덱스 예시
CREATE INDEX idx_products_name_trgm ON products USING gin (name gin_trgm_ops);
-- 부분 일치나 유사도 검색 가속
GiST 인덱스 예시
CREATE INDEX idx_products_name_trgm_gist ON products USING gist (name gist_trgm_ops);
-- GiST는 일부 쓰기 부하에서 유리할 수 있음
실제 쿼리 예시
다음은 사용자 입력을 이용한 검색 패턴이다. 유사도 기준으로 정렬하거나, % 연산자를 이용해 임계값 기반 필터링이 가능하다.
유사도 정렬
SELECT id, name, similarity(name, 'iphon') AS sim
FROM products
WHERE name % 'iphon'
ORDER BY sim DESC
LIMIT 10;
임계값 조정과 직접 비교
SELECT set_limit(0.3); -- % 연산자에 적용되는 유사도 임계값 설정
SELECT * FROM products WHERE name % 'galaxi';
-- 또는 직접 점수 비교
SELECT * FROM products WHERE similarity(name, 'galaxi') > 0.25 ORDER BY similarity(name, 'galaxi') DESC;
튜닝 포인트
환경과 데이터 특성에 따라 성능과 정확도의 균형을 맞춰야 한다. 주요 고려사항은 다음과 같다.
- 인덱스 유형 선택: 읽기 중심이면 GIN, 쓰기가 잦으면 GiST 고려
- set_limit 값: 낮추면 더 많은 후보가 반환되지만 성능 저하 유발 가능
- 쿼리 형태: WHERE 절에서 바로 % 연산자를 사용하면 인덱스가 효과적
- 정규화와 전처리: 불필요한 공백 제거, 소문자 변환 등으로 일관성 확보
적용 사례와 설계 팁
검색 UI나 자동완성, 관리자 도구 등에서 pg_trgm이 자주 쓰인다. 설계 시 고려할 점은 다음과 같다.
- 빠른 응답을 위해 인덱스 우선 적용
- 긴 텍스트 필드보다는 검색 대상 필드에 제한적으로 적용
- 결과 정렬은 similarity 점수를 사용해 사용자 기대에 맞춤
주의사항
pg_trgm은 모든 상황에 만능은 아니다. 예를 들어 의미 기반 검색이나 어절 단위 의미 분석이 필요한 경우에는 full-text search나 외부 검색엔진이 더 적절하다. 또한, 인덱스 생성과 유지에 디스크와 시간이 필요하므로 테스트를 통해 적절한 필드를 선정해야 한다.
결론
pg_trgm은 PostgreSQL에서 근사 문자열 검색과 부분 일치 성능을 개선하는 실용적인 도구다. 간단한 설치와 인덱스 추가만으로도 검색 속도와 품질을 향상시킬 수 있다. 프로젝트 요구에 따라 인덱스 유형과 유사도 임계값을 조정하면 최적의 결과를 얻을 수 있다.
참고 팁
- 테스트 데이터를 준비해 성능과 정확도를 비교한다.
- 복수 언어를 다룰 때는 전처리 규칙을 일관되게 적용한다.
- 필요 시 pg_trgm과 full-text search를 조합해 사용한다.