legacy/Pin-Table 성능 개선 기록

검색 성능 개선 #11 Full-Text Index 검색조건

3hoon 2023. 2. 26. 15:45

Full-text index를 적용하고 난 이후 검색 성능은 굉장히 개선되었지만

Full-text index가 내가 검색어를 검색했을때 그 해당하는 검색어가 포함하는 경우를 찾아주는것이라 생각했는데

특정 문자열은 검색이 안되는 현상이 있었다.


문제현상

Full-text index 적용확인

%검색어%로 검색했을때

“성수감자탕”을 포함하는 가게가 아주 잘 나오는 것을 볼 수 있다.

 

Full-text-index로 검색했을때

“성수감자탕”을 포함하는 가게가 없다고 한다.


해결시도

코드에서 먼저 확인을 했다.

debug를 했을때 코드는 정상적으로 읽히는 것을 확인을 했고

where절의 Full-text index 쿼리도 잘 날아가는 것을 볼 수 있다.


문제의심

select * from store where match(store_name)against("순대국*"in boolean mode);

좀 더 유효한 수치를 얻기 위해 여러가지 키워드로 검색을 해보았고 “순대국”이라는 키워드에서 힌트를 찾았다.

  1. 띄어쓰기를 기준으로 한다면 “순대국” 키워드가 가장 전방에 위치하고 있다.
  2. 특수문자를 기준으로 한다면 “순대국” 키워드가 가장 전방에 위치하고 있다.

산책하면서 곰곰히 생각을 해보면서

“혹시 색인하는 과정에서 검색이 안되는 문제가 생기지 않았을까?”

라는 고민을 했다.


문제해결

문제는 인덱싱 방식이 stop-word parser로 기본으로 잡혀 있었기 때문에 그랬다.

MYSQL에 built-in 된 parser가 두가지가 있는데

stop-word parser와 N-gram parser 두가지가 있다.

stop-word parser의 특징은

띄어쓰기나 문장 기호 등을 기준으로 키워드를 추출해내고 그 결과를 인덱스로 구축하는 방식인데

이러한 방식은 키워드 전부가 일치하거나 전방의 단어가 일치 할때만 결과를 가져올 수 있다는 특징이 있다.

즉 노트북과 삼성노트북이라는 키워드가 있을때 “노트북”이라는 키워드로 검색을 한다면 삼성노트북은

검색 대상에서 제외되는 단점이 있다.

 

그에 반해 N-gram parser 방식은 본문의 내용을 모두 잘라서 인덱스를 만들어서 사용하기 때문에

좀 더 상세하고 복잡한 검색을 가능하게끔 만들어주는 역할을 한다.

또한 중국어, 일본어, 한국어까지 지원하는 특징이 있다.

 

N-gram parser는 MYSQL 5.6 이후부터 MYSQL 기본 built-in parser로 되어 있으며

현재 우리 프로젝트에서 사용하는 MYSQL 버전은

이므로 사용이 가능하다.

 

N-gram parser를 적용해본다면

create fulltext index store_full_idx on store(store_name) with parser ngram;

기본적인 Full-text index 쿼리에서 with parser ngram을 추가해 인덱스를 생성하면 된다.


 

N-gram parser 적용전

%검색어% 쿼리

N-gram parser 적용후

위 사진처럼 “성수감자탕”을 포함하면서도 검색 성능도 full scan이 아닌 Full-text index 방식으로 바뀌었다.