RDMS/PostgreSQL

[PostgreSQL] 텍스트 검색 최적화: phraseto_tsquery - 컴도리돌이

컴도리돌이 2024. 9. 7. 09:00
728x90

이번에 검색 기능을 최적화해야 하는 쿼리가 있었습니다. 검색 시스템의 성능은 사용자 경험에 크게 영향을 미치기 때문에, 빠르게 정확한 검색 결과를 제공하는 것이 매우 중요하죠. 처음에 유저가 검색한 데이터를 보여주기 위해서, PostgreSQLLIKE 연산자를 사용하여 텍스트 검색을 처리하곤 했습니다. 그러나 데이터가 많이 지면서 검색 성능이 눈에 띄게 저하되는 상황이 많이 놓였죠 😓

특히, 다중 단어 검색에서는 문제점이 더욱 두드러집니다. 예를 들어, "postgresql performance tuning"과 같은 문구를 검색할 때, LIKE 쿼리는 부분 단어 매칭에만 의존해 결과가 너무 광범위하거나 불안전했습니다. 성능도 상당히 떨어지고요. 🤨 

 

그래서 이번에는 단순한 키워드 검색이 아닌, 문장을 기반으로 한 더 효율적인 검색이 가능한 phraseto_tsquery를 사용해서 검색 기능을 최적화하려고 합니다. 기존의 검색 문제를 해결하면서 성능까지 개선되는 두 마리 토끼를 모두 잡을 수 있죠 👍


phraseto_tsquery 예시

LIKE 쿼리는 사용자가 입력한 모든 단어가 포함된 결과를 정확히 찾지 못하고, 부분 매칭된 결과가 다수 반환됩니다. 또한 데이터 양이 커질수록, 특히 다중 단어 검색 시 성능 저하가 심해져요.

-- 기존 LIKE 쿼리
SELECT * FROM korea_addres_table WHERE ko_address LIKE '%중구 종로2가%';

-- phraseto_tsquery를 사용한 쿼리
SELECT * FROM korea_addres_table WHERE tsvec_words @@ phraseto_tsquery( '중구 종로2가' );

 

phraseto_tsquery는 단어의 순서와 관계없이 입력된 문구를 분서하여, 해당 문구에 해당하는 텍스트만을 더 정확하게 찾도록 합니다. 이를 통해 일관된 검색 결과를 얻을 수 있어요.


phraseto_tsquery의 원리와 개념

phraseto_tsquery는 사용자가 입력한 문구를 구문 단위로 분해하여, 이를 텍스트 서치 엔진에서 처리할 수 있는 쿼리로 변환해요. 기본적으로 to_tsquery와 비슷하지만, 입력된 문구의 단어 순서를 고려하지 않으며, 보다 문장 중식의 검색을 가능하게 돼요. 

 

작동 방식은 다음과 같습니다: 

  1. 문구 파싱: 사용자가 입력한 문구를 파싱해 각 단어들을 추출합니다.
  2. 단어 사이의 관계 정의: 각 단어들이 특정 거리에 위치해 있는지를 정의하고, 문구의 의미를 보존합니다.
  3. tsquery 생성: 이 파싱 된 결과를 기반으로 tsquery 객체를 생성하여 실제 검색에 사용됩니다. 

아래는 참고하 ppt 자료인데, 그림도 있어서 유용하게 볼 수 있어요. 😊

 

Better Full Text Search in PostgreSQL

Better Full Text Search in PostgreSQL - Download as a PDF or view online for free

www.slideshare.net


성능 개선

phraseto_tsquery를 사용하면 다음과 같은 성능 개선이 나타났어요. 200만건의 데이터에서 테스트를 하였습니다 📊:

검색 방식 평균 응답 시간 (ms) 결과의 일관성
LIKE 쿼리 987.901 ms 보통
phraseto_toquery 0.944 ms 높음

 

위에 표에서 보듯이, phraseto_tsquery를 사용하면 놀라운 성능 차이를 확인할 수 있어요. LIKE 쿼리에서는 거의 1초 정도 걸리는 쿼리가 phraseto_toquery를 사용하면 1초의 천분의 일 시간이 걸리네요. 비교하면 약 1047배가 향상될 뿐 아니라, 보다 일관된 검색 결과도 얻을 수 있어요. 


phraseto_tsquery는 특정 구문을 검색할 때 사용자가 입력한 문장 그대로를 정확히 검색해야 하는 상황에서 유용한 거 같아요. 사용자가 "종로2가"를 검색해야 하는데, "종로 2가"를 검색하면 원하는 검색 결과를 얻을 수 없네요.😓 

물론 검색 성능을 향상하기 위해 phraseto_tsquery를 사용하는 것은 훌륭한 선택지일 거예요. 다중 단어 검색에서 성능과 일관성을 모두 개선할 수 있으며, 특히 대규모 데이터 환경에서 큰 이점을 제공할 거예요 👍


 

[PostgreSQL] NLP 자연어 기반 구문 검색[Full-Text Search] - 컴도리돌이

Elasticsearch에 대해 정리할 때, 우연히 PostgreSQL에 대한 Full Text Search에 대한 포스팅한 글을 보게 되었습니다. 놀랍게도 PostgreSQL에서도 Full Text Search를 지원하고, 놀랍게도 제가 관리하는 페이지에서

comdolidol-i.tistory.com

 

Full Text Search를 활용한 데이터베이스 성능 향상

1. 문제상황 긴 텍스트에서 단순 like 조합 외 방법으로 유사 문자열 검색 (Ex. Susan loves hiking 을 “love hike” 이라는 키워드로 검색하고자 함) RDBMS에서 수천만 건의 데이터 처리 시 긴 문자열 검색

junhkang.tistory.com

 

12.3. Controlling Text Search

12.3. Controlling Text Search # 12.3.1. Parsing Documents 12.3.2. Parsing Queries 12.3.3. Ranking Search Results 12.3.4. Highlighting Results To implement full …

www.postgresql.org