8.5 전문 검색 인덱스
8.5 전문 검색 인덱스
지금까지의 인덱스는 크지 않은 데이터나 작은 값에 대한 인덱싱 알고리즘을 사용하였다.
MySql 의 B-Tree는 실제 컬럼 값이 1MB 라도 1_000 바이트(MyISAM) 또는 3_072 바이트까지만 잘라서 사용
전체 일치 또는 좌측 일치만 검색 가능
내용 전체를 인덱스화시켜 특정 키워드가 포함된 문서를 검색하는 전문(Full Text) 검색에는 B-Tree를 사용할 수 없다.
전문 검색(Full Text Search) 인덱스 : 문서 전체에 대한 분석과 검색을 위한 인덱싱 알고리즘, 일반화된 기능의 명칭으로 알고리즘 명이 아님.
8.5.1 인덱스 알고리즘
전문 검색에서는 문서 본문의 내용에서 사용자가 검색하게될 키워드를 분석해내고 빠른 검색용으로 사용할 수 있게 이러한 키워드로 인덱스를 구축함.
8.5.1.1 어근 분석 알고리즘
MySQL 서버의 전문 검색 인덱스는 다음 2가지 과정을 거쳐 인덱싱을 함.
- 불용어(Stop Word) 처리
검색에서 별 가치가 업슨ㄴ 단어를 모두 필터링해서 제거하는 작업
불용어의 개수가 많지 않기 때문에 알고리즘 구현 코드에 상수로 정의해 사용하는 경우가 많고 유연성을 위해 DB화 해서 사용자가 추가, 삭제 할 수 있게 구현하는 경우도 있음
MySQL은 소스코드에 정의되어 있지만 이를 무시하고 정의할 수 있는 기능을 제공 - 어근 분석(Stemming)
검색어로 선정된 단어의 뿌리인 원형을 찾는 작업
MySQL 서버는 MeCab 이라는 형태소 분석 라리브러리를 플러그인 형태로 사용할수 있게 지원
8.5.1.2 n-gram 알고리즘
MeCab을 위한 형태소 분석이 전문적인 전문 검색 알고리즘이어서 만족스러운 결과를 위해 많은 시간과 노력이 필요
=> n-gram 알고리즘 도입
n-gram : 본문을 무조건 몇 글자씩 잘라서 인덱싱하는 방법.
형태소 분석보다 알고리즘이 단순하고 언어에 대한 이해와 준비작업이 필요없음.
다만 인덱스의 크기가 상당히 커짐.
n은 인덱싱할 최소 글자 수 인데 보통 2-gram(Bi-gram)을 사용함.
2-gram 토큰 분리방법
To be or not to be. Taht is the question.
공백과 마침표 기준으로 10 개의 단어로 구분되고 2 글자씩 중첩해서 토큰으로 분리.
- To : To
- be : be
- or : or
- not : no, ot
- to : to
- be : be
- That : Th, ha, at
- is : is
- the : th, he
- question : qu, ue, es, st, ti, io, on
이렇게 구분된 토큰을 인덱스에 저장. 중복된 토큰은 하나의 인덱스 엔트리로 병합.
불용어와 동일하거나 불용어를 포함하는 경우 걸러버림.
-- 불용어 확인
SELECT * FROM information_schema.INNODB_FT_DEFAULT_STOPWORD;
최종 등록 인덱스
입력 | 불용어 일치 | 불용어 포함 | 출력(최종 인덱스 등록) |
---|---|---|---|
at | O | ||
be | O | ||
be | O | ||
es | es | ||
ha | O | ||
he | he | ||
io | O | ||
is | O | ||
no | no | ||
on | o | ||
or | o | ||
ot | ot | ||
qu | qu | ||
st | st | ||
Th | Th | ||
th | th | ||
ti | O | ||
To | O | ||
to | O | ||
ue | ue |
이렇게 구분된 토큰을 B-Tree에 저장하게 됨.
8.5.1.3 불용어 변경 및 삭제
앞서 본 불용어 처리 중 "a" 와 "i" 가 들어간 토큰들은 모둔 걸러졌다.
이런 불용어 처리는 사용자를 더 혼란스럽게 할 수도 있음.
그래서 불용어 처리를 무시하거나 사용자가 직접 불용어를 등록하는 방법을 권장함.
전문 검색 인덱스의 불용어 처리 무시
- 스토리지 엔진에 관계없이 MySQL 서버의 모든 전문 검색 인덱스에 대해 불용어를 완전 제거하는 방법.
MySQL의 설정파일(my.cnf, my.ini)의 ft_stopword_file 시스템 변수에 빈문자영을 설정하면됨.(재시작시 반영)
사용자가 정의한 불용어 파일의 경로를 넣으면 사용자가 정의한 불용어 목록을 적용함. - InnoDB 스토리지 엔진을 사용하는 테이블의 전문 검색 인덱스에 대해서만 불용어 처리를 무시.
innodb_ft_enable_stopword 시스템 변수를 off로 설정하면됨.
서버가 실행중인 상태에서도 변경 가능.set global innodb_ft_enable_stopword=off;
사용자 정의 불용어 사용
- 불용어 목록을 파잉로 저장하고 설정파일의 ft_stopword_file 설정에 등록
ft_stopword_file='/data/my_custom_stopword.txt'
- 불용어 목록을 테이블로 저장
InnoDB 테이블의 전문검색 엔진에만 사용 가능.create table my_stopword(value varchar(30)) engine = InnoDB; insert into my_stopword(value) values ('MySQL'); set global innodb_ft_server_stopword_table = 'mydb/my_stopword';
innodb_ft_user_stopword_table 시스템 변수를 사용하는 방법도 있음.
사용 방법은 동일함.
여러 전문 검색 인덱스가 서로 다른 불용어를 사용해야 하는 경우 사용하면됨.
8.5.2 전문 검색 인덱스의 가용성
전문검색 인덱스 사용 조건
- 쿼리 문장이 전문검색을 위한 문법(match ... against ...)을 사용
- 테이블이 전문 검색 대상 칼럼에 대해서 전문 인덱스 보유
-- 예시
CREATE TABLE tb_test(
doc_id int,
doc_body text,
primary key (doc_id),
fulltext key fx_docbody(doc_body) with parser ngram
) engine = InnoDB;
-- 풀스캔
select * from tb_test where doc_body like '%애플%';
-- 전문 검색 인덱스
select * from tb_test
where match(doc_body) against('애플' in boolean mode);
-- 전문 검색 인덱스를 구성하는 컬럼들이 match 괄호에 모두 명시되어 있어야함.
'Study > Real-MySQL' 카테고리의 다른 글
8.7 멀티 밸류 인덱스 (0) | 2024.01.05 |
---|---|
8.6 함수 기반 인덱스 (0) | 2024.01.05 |
8.4 R-Tree 인덱스 (0) | 2024.01.05 |
B+Tree index (1) | 2023.12.26 |
8.3 B-Tree 인덱스(2) (2) | 2023.12.26 |
댓글