Rlog

[MySQL] ngram parser 를 이용할때 'a' 가 검색이 잘되지 않는 이유 본문

데이터베이스/MySQL

[MySQL] ngram parser 를 이용할때 'a' 가 검색이 잘되지 않는 이유

dev_roach 2022. 3. 3. 00:07
728x90

이전에 ngram parser 를 이용한 자동완성 기능을 만들었다고 했었다.

실제로 적용해보니 문제가 있었는데 아래와 같은 문제가 발생했다.

위의 화면을 보면 'ach' 가 포함되어 있는 것만 검색하려고 BOOLEAN MODE 를 적용해서 쿼리를 날렸음에도 ach 가 없는 김루루 라는 콜럼이 검색되게 된다. 이유가 무엇일까?

 

문제 추론

처음에는 MySQL 의 Ngram Parser 의 Token size 를 1로 저장해놔서 아래와 같이 잘려서 그냥 알파벳만 들어가 있어도 검색이 되나 싶었다.

하지만 위와 같은 추론을 하기에는 무언가 연관성이 없어보였다. 

왜냐하면 다른 글자로 검색을 해봤을때는 너무 잘 나오는 것이다. 이때까지만 해도 'a' 가 문제인줄을 몰랐다.

그래서 알아보던 도중 ngram parser 를 이용한 fulltext search 를 할때는 유사성 점수(score) 를 확인할 수 있는데 이를 통해서 ORDER 순서를 바꿔서 위로 올리는 방법으로 해결해야겠다! 라는 생각으로 문제해결 방법에 도달해서 아래와 같은 쿼리를 작성했다.

근데 문제는 이때부터 봉착했다.

이상하게도 왠걸 둘의 유사성 점수가 같은 것이다.

이때부터 당혹감을 감추지 못했는데, 그래서 처음에 말했던 한글자씩 Token 을 분해하여 검색한 것이 맞나? 이생각이 들었다.

사실 row 자체가 300건 정도로 운영될 것이라 Like 쿼리를 써도 무방했으나, fulltext search 를 한번 도입해보고는 싶었다.

일단 그래서 DBA 분에게 이 방법에 대해서 더 좋은 방법이 없는지 한번 질문해보았다.

그래서 부랴부랴 답변을 확인해보고 stop_word 에 대해서 공부해보게 되었다.

아 여기서 짚고 넘어가는데 위의 예시코드는 회사 코드가 아니다 ㅋㅋ. 

블로그 예시를 위한 내가 직접짠 예시 코드이다.

문제 해결

일단 stop_word 를 확인해보니 아래와 같은 것들이 존재했다.

정관사 등 영어로서 뭔가 단어로서 활용되지 않는것들(?) 여하튼 그런것들만 모아 놓은것이다.

간단히 설명하면 위의 stop_word 는 구분자로서 활용된다. 

즉, 구분자를 무시하고 검색을 하게 되는데.. 내가 생각해보니 token 화를 1개 단위로 하다보니

이 stop_word 에 'a' token 이 걸려서 'ach' 가 아닌 'ch' 로 잡혀서 검색이 됬겠구나 라는 생각이 들었다.

그래서 이 옵션을 끄는 방법을 알아보게 되었다.

 

my.cnf 파일에 아래와 같은 셋팅값을 추가해주면 된다.

하지만 static parameter 인지 껐다 켜야지만 먹히는 것 같았다. 그래서 아래옵션을 추가하고 껐다 켰다.

innodb_ft_enable_stopword = 0;

일단 해당 옵션이 잘꺼진걸 확인할 수 있다.

 

껐다 키고 나면 fulltext index 를 다시 구성해야 한다고 하더라, 그래서 fulltext Index 를 다시 구성했다.

CREATE FULLTEXT INDEX ft_idx_name_email ON user(name, email) with parser ngram;

이제 다시 검색해보자.

이젠 아까와 다르게 잘 나오는 것을 알 수 있다.

 

느낀점

이번에 삽질하면서 많은 것을 좀 공부하게 되었다.

특히 FullText Index 에 대해서 좀 공부하게 되었는데 어떤 사람들은 기존의 Like 를 써오던 부분에 Fulltext index 를 적용할만 하다고 느끼면 적용해서 성능향상을 하시는 분들도 계셨다. 나도 그래서 생각이 든것이 '%searchText%' 를 쓰고 있다면 어느정도 성능을 생각해보고 FullText 가 가능한지, 혹은 다른 방법은 없을지 고민할 수 있겠단 생각이 들었다.

 

이런 방향성에서 문제 해결능력이 한층 길러진것 같아서 기분이 좋았다.

'데이터베이스 > MySQL' 카테고리의 다른 글

인덱스 스캔 방식  (0) 2021.11.08
MySQL Index  (0) 2021.10.31
MySQL Lock System  (0) 2021.10.25
MySQL 에 쿼리가 들어왔을때?  (0) 2021.10.21
InnoDB 엔진의 특성  (2) 2021.10.12