TIN - Postgres용 전문 검색
요약
본 글은 Postgres 데이터베이스의 전문 검색 기능(Full-Text Search)에 대한 심층적인 논쟁을 다룹니다. LLM 기반 아키텍처와 기존 DB 엔진의 성능, 그리고 BM25 같은 고급 관련도 알고리즘 구현 가능성에 대해 비판적으로 분석합니다. 궁극적으로는 PostgreSQL 내장 기능과 외부 솔루션 간의 기술적 우위 및 한계를 비교하고 있습니다.
핵심 포인트
- Postgres 전문 검색은 LLM 조합보다 숙련된 개발팀 경험이 중요함.
- BM25 같은 고급 관련도 알고리즘 구현은 스토리지 엔진 레벨에서 어려움이 있음.
- PostgreSQL 내장 기능(tsvector/tsquery)과 외부 솔루션 간의 성능 및 기능적 차이가 존재함.
- 최종적으로는 Postgres 자체 기능을 활용하는 것이 기술적 안정성과 효율성 측면에서 유리할 수 있음을 시사함.
상당 부분 동의하지만, 분야별 전문가가 더 빠르게 일할 수 있게 된 것도 큰 요인임. PlanetScale이 에이전트 기반 개발을 활용했다고 가정하더라도, 그 수준의 성능을 달성한 건 경험 많은 Postgres 개발팀이 있기 때문일 것임.
Postgres 내부 구조에 대한 지식이 있어야 모델을 이 글에 나온 아키텍처로 유도할 수 있음. 모델 혼자 할 수 있는 일은 아니며, 최고 수준의 전문가와 LLM의 조합이 큰 성과를 만들어 냄.
다만 AI 연구소 내부에서는 조금 다른 양상도 보임. 그곳에서만 감당할 수 있는 규모로 토큰을 사용하면, 모델 자체의 통찰로 새로운 일을 해내는 모습도 보여 줌.
가설에 완전히 반대하는 건 아니지만, TIN에서 어려운 부분은 오래전부터 있던 BM25가 아니라 이를 둘러싼 스토리지 엔진 구현으로 보임. 초당 수천 건의 갱신이 발생하는 환경에서 세그먼트를 병합하는 일에 LLM이 특히 능숙할까? Claude가 더는 성능을 개선할 수 없다고 했는데도 직접 계속 파고들어 상당히 개선한 적이 몇 번 있음.
더 결정적인 반례는 ParadeDB의 pg_search가 에이전트 코딩보다 몇 년 먼저 나왔다는 것 아닐까?
Neki도 같은 방식이고, 점점 이 회사의 기본 방침이 되어 가는 듯함. 이 조건만으로도 내게는 도입 대상에서 제외됨. 지금은 그 규모가 필요한 과제가 없지만 과거에는 있었음.
Postgres 라이선스상 허용되더라도 개인적으로는 개운하지 않음. 정확히는 Postgres용 전문 검색이 아니라 자사 호스팅 Postgres용 전문 검색이므로 제목도 다소 오해를 부름.
베어메탈을 지원하지 않는 것이 걸림돌임. 우리 베어메탈 서버에서 PlanetScale을 쓰고 싶음.
Postgres 매뉴얼을 읽어 보길 권함. 내장 검색 기능이 굉장히 강력함.
tsvector/tsquery를 뜻한다면(https://www.postgresql.org/docs/9.6/textsearch-intro.html), 좋은 기능이지만 전체 문서 집합을 고려한 순위 산정이 빠져 있음. PostgreSQL 내장 전문 검색은 해당 행의 데이터만으로 각 행의 점수를 계산함. BM25 같은 관련도 알고리즘은 전체 문서 집합의 통계를 고려함. 여러 단어로 검색할 때 전체 문서에서 더 드문 단어와 일치하는 문서에 더 높은 점수를 주는 방식임. 이런 확장들이 제공하는 것이 바로 이 기능임.
자세히 읽어 보면 내장 검색보다 훨씬 나은 성능을 내세우고 있음. 내장 검색에 없는 기능도 제공한다는 뉘앙스지만, 구체적으로 무엇인지는 명확하지 않음.
다른 열의 조건까지 포함하는 질의를 같은 인덱스로 처리하는 기능 정도인 듯함. 나머지는 약 20년 전부터 있던 내장 검색 기능과 대응되는 것으로 보임.
내장 검색은 문서 집합 전체의 통계를 사용하는 점수 계산을 지원하지 않아 TF-IDF나 BM25를 쓸 수 없음. 그 기능이 필요 없다면 괜찮겠지만, 내 경험상 검색 결과가 훨씬 나쁨.
내장 검색은 있지만, 굉장히 강력하다고 하기는 어려움.
Postgres에는 함수 기반 인덱싱과 쿼리 최적화에 통합된 상당히 정교한 전문 검색 패키지 pg_fts(tsvector/tsquery/tsrank) 가 있음. 그런데 왜 Postgres 핵심 기능도 아닌, 바이브 코딩으로 만든 것을 써야 할까?
SQLite FTS는 기본적으로 Lucene 질의를 지원하고 성능도 매우 좋음. 기억하기로는 시간이 지나면 쓰기만 상당히 느려짐.
PostgreSQL이 이 구현을 자체 데이터베이스에 붙이지 못하는 이유가 늘 궁금했음. ts_query를 써 본 결과는 그다지 좋지 않았음. LIKE보다 조금 나은 정도인데 인덱스 크기는 터무니없이 커짐. 이 확장이 오픈소스가 되어 실제 환경에서 시험할 수 있다면 적절한 활용처를 찾을 수 있을 듯함.
SQLite FTS는 단일 쓰기 잠금 아래의 보조 B-트리에 의존함. 반면 Postgres의 인덱스 접근 방식은 검색어별 문서 목록을 물리적인 ctid 튜플에 직접 연결하면서, MVCC 가시성 검사와 힙 튜플의 빈번한 변경에도 올바르게 동작해야 함.
Postgres용 전문 검색 솔루션들이 하나같이 잘하지 못하는 영역은 다국어 지원이라고 봄.
이 제품도 CJK 언어 지원을 명시하지 않음. 중국어 등을 글자당 하나의 토큰으로 처리하면 검색은 되겠지만 비효율적임. 확인한 범위에서는 databases를 database로 바꾸는 어간 추출도 없어, 연관된 단어가 나올 것으로 기대하는 검색에서 결과가 빠질 수 있음. 대소문자와 악센트 정규화만 하는 건 작동은 해도 다소 무식한 접근임.
이상적으로는 레코드별 언어 지정과 언어별 토큰화, 어간 추출, 주요 언어에 바로 쓸 수 있는 설정이 필요함. Postgres 내장 기능에도 빠진 언어가 많음. CJK는 단어 경계에서 토큰화하고, 악센트와 대소문자 정규화는 선택할 수 있어야 함. 대부분 영어 콘텐츠만 가정하는 듯하며, 이 조건을 모두 충족하는 솔루션은 아직 찾지 못함.
SQLite와 MSSQL에서 SQL 내부의 전문 검색을 쓰는 데 어려움을 겪음. 관계형 데이터 처리와 검색용 문서 저장 방식 사이에 상당한 불일치가 생기는 경우가 많음.
그래서 늘 SQL을 원본 데이터 저장소로 두고 외부 Lucene 인덱스를 구축·유지하는 방식을 선호해 왔음. 이제 통합 전문 검색이 이런 혼합 구조를 쓸 이유가 없을 정도로 발전했을까? 이 서비스에서는 어느 정도까지 맞춤 설정이 가능할까?
TIN 개발자 중 한 명이며, 내 사용자명을 검색해 보면 이 분야에서 오래 일해 왔다는 걸 알 수 있음. 첫 번째 질문에 대한 답은 간단히 말해 그렇다는 것임.
두 번째 질문과 관련해서는 TIN이나 PlanetScale이 제공하지 않는다고 생각하는 맞춤 기능이 구체적으로 무엇인지 궁금함. 그런 기능은 신속하게 구현할 수 있음.
내 경험상 대규모 텍스트 역색인을 데이터베이스 안에 직접 두는 것은 꽤 흔함. 반드시 큰 문서는 아니더라도 대량의 자유 형식 텍스트를 저장하는 경우가 많음. BM25와 Unicode의 BreakIterator로 구현하는 건 좋은 방법임.
사실상 데이터베이스 안에 Lucene을 넣는 셈이며, 이미 데이터베이스가 크다면 충분히 합리적임. 검색을 어떻게든 밖으로 빼려는 곳은 보통 데이터베이스가 너무 커지는 걸 피하려는 것인데, 결국 커다란 데이터베이스까지 떠안아 양쪽의 단점만 얻는 경우도 많음.
PlanetScale을 써 보고 싶지만, Neon의 브랜치 모델에 완전히 의존하고 있음. 정말 빠져나오기 어렵게 잘 만들었음!
AI 자동 생성 콘텐츠
본 콘텐츠는 RSS: GeekNews (한국어)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기