본문 바로가기
MySQL별책부록

MySQL Ver. 5.7 InnoDB Fulltext Search 기능 개선

by 모모레 2016. 6. 30.

1. InnoDB Plugin Parser 지원 

MySQL Ver. 5.7.3부터 InnoDB Fulltext Search 에 대한 플러그인 파서를 지원한다. 


이 파서 플러그인은 두가지의 규칙을 가지고 동작한다. 


1. 이 플러그인은 bulit-in parser의 기능을 대체할 수 있다.  

즉, 이 플러그 인이 파싱된 입력 내용을 읽어서 단어를 잘라서 서버에 단어를 전달하는 작업을 모두 진행한다는 것을 의미한다. 


2. 이 플러그인은 builtin-parser와 결합하여 front end 로서의 서비스를 제공할 수 있다. 

즉, 일반적인 파싱 규칙으로 입력값으로 부터 텍스트를 추출하고 파서에 전달하여 단어를 분리하게 할 수 있다는 것을 의미한다. 


위 규칙을 가지고 사용자는 MySQL 서버에 플러그인 파서를 만들어서 사용할 수도 있고, 만들어진 플러그인 파서를 로딩하여 사용할 수도 있다. 


2. InnoDB Full-Text : N-gram 파서

내장된 InnoDB Fulltext 파서는 라틴계열 언어에 기반하여 동작하게끔 만들어져 있다. 그래서 동북아 계 언어는 Chinese, Japanese, Korean (CJK) 언어에 대해서는 제대로 동작하지 않는 단점을 가지고 있었다. 하지만, MySQL Ver. 5.7 부터 플러그인 형태의 FullText 파서를 지원하기 시작했고, 빌트인 파서의 위와 같은 불편함을 해소하기 위해  MySQL Ver. 5.7.6부터 N-gram 파서를 사용할 수 있게 기능이 개선되었다. 


2.1 N-gram 이란?

Full-Text 검색에서 n-gram은 여러 단어(음절이아님)가 띄어쓰기 없이 쓰였을때 연속적으로 나열된 음절들을 뜻한다. 즉, "abcd"란 문자열이 있을때 이것을 n-gram으로 나누면 다음과 같이 나뉘어 지게 된다. 


[N-gram 의 예제]


N=1 : 'a', 'b', 'c', 'd';

N=2 : 'ab', 'bc', 'cd';

N=3 : 'abc', 'bcd';

N=4 : 'abcd';



2.2 간단한 사용 예제 

N-gram 파서는 기본적으로 사용할 수 있게 설정되어 배포된다. 만약, 사용하고 싶다면 DDL 구문에 다음과 같이 "WITH PARSER ngram" 구문을 추가하여 테이블을 생성하면 된다.  다음과 같은 사용법은 MySQL Ver. 5.7.6 부터 사용이 가능하다. 


mysql> CREATE TABLE articles

(

        FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,

        title VARCHAR(100),

        FULLTEXT INDEX ngram_idx(title) WITH PARSER ngram

) Engine=InnoDB CHARACTER SET utf8mb4;

Query OK, 0 rows affected (1.26 sec)

 

mysql> # ALTER TABLE articles ADD FULLTEXT INDEX ngram_idx(title) WITH PARSER ngram;

mysql> # CREATE FULLTEXT INDEX ngram_idx ON articles(title) WITH PARSER ngram;



N-gram 파서와 관련된 시스템 변수로 ngram_token_size가 있다. 이 시스템 변수는 어떤 음절로 단어를 잘라서 분석할 것인지를 결정하는 토큰의 최소단위를 선택한다. 기본값은 2이다. 1~10까지 중에 선택하여 설정할 수 있다. 


2.3 빌트인 파서와 N-gram 파서의 다른점 

빌트인 파서와 N-gram 파서는 다음과 같은 점이 다르다. 


1. 빌트인 파서는 innodb_ft_min_token_size와 innodb_ft_max_token_size 시스템 변수를 사용하여 토큰을 나누지만, N-gram 파서는 ngram_token_size 시스템 변수만 사용하여 토큰을 나눈다. 

2. 빌트인 파서는 stopword 테이블에 저장된 단어가 토큰과 동일하면 그것을 인덱스에 추가하지 않지만, N-gram 파서는 토큰으로 나눈 단어에 stopword 테이블에 저장한 단어가 포함되어있어도 인덱스에 추가하지 않는다. 동일한 토큰만 제외하면 쓸모없는 토큰들이 너무 많아지기 때문이다. 

3. White space(공백) 는 항상 hard-coded stopword로 무시된다. 즉, 토큰을 나눌때 포함되지 않는다. 


2.4 모니터링 방법

INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE 와 INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE을 조회하면 특정 Full-text 인덱스에 대한 정보를 확인할 수 있다. 


2.5 지원하는 문자열 검색 모드 

단어를 검색하는데 사용되는 모드는 2가지가 있다. 


2.5.1 NATURAL LANGUAGE MODE

이 방식은 검색하려는 문자를 토큰으로 나누었을때 그 n-gram 값을 포함하는 문자열을 모두 검색해서 보여주는 방식을 말한다. 


2.5.2 BOOLEAN MODE 

이 방식은 검색하려는 문자만 검색해서 보여주는 방식을 말한다. 즉, 토큰 사이즈와 상관없다. 


2.6 Wildcard 검색 

다음과 같은 방식으로 Wildcard 검색이 이루어진다. 

1. 만약, Wildcard앞의 문자가 ngram_token_size보다 적은 수라면, 해당 검색 쿼리는 그 문자로 시작하는 모든 n-gram token에 대해 검색하여 검색 결과를 보여주게 된다. 


2. 만약, Wildcard앞의 문자가 ngram_token_size보다 큰 수라면, wildcard 검색은 phrase 검색과 같이 동작한다. 즉, wildcard는 무시된다. 



2.7 Phrase 검색 

Phrase 검색은 n-gram 토큰의 phrase 검색으로 변환된다. phrase 검색이 되면 검색하고자 하는 구의 모든 형태가 그대로 맵핑되어야 한다. 즉, '한 사람'과 '한사람'은 다른 결과값을 보여주게 된다. 


3. InnoDB Full-Text :MeCab Parser 

MeCab Parser는 일본어 전용 분석 파서이다. 그래서 여기서는 다루지 않겠다. 



4. 옵티마이져에 대한 Full-Text 성능 개선 (?)



http://mysqlserverteam.com/innodb-full-text-n-gram-parser/

http://mysqlserverteam.com/innodb-supports-plugin-parser-in-fulltext-index/

http://dev.mysql.com/worklog/task/?id=7123