데이터베이스에 저장된 레코드중 거대한 문서 내용들에 대한 키워드를 인덱싱하기 위해서는 전문 검색 인덱스를 사용한다.
예를 들어서 TEXT와 같은 형의 데이터를 검색하기 위해서는 InnoDB나 MyISAM에서 제공하는 B-Tree 인덱스를 사용할 수 없다.
이러한 데이터를 검색하는 것을 Full Text Search 인덱스라고 하는데, 전문 검색 인덱스는 일반화된 기능의 명칭이지 전문 검색 알고리즘의 이름을 지칭하는 것은 아니다.
전문 검색 인덱스에는 문서의 키워드를 인덱싱하는 기법에 따라 구분자(Stopword)와 n-gram을 나누어 생각해볼 수 있다.
이외의 알고리즘은 그다지 알려지지도 않고 특히나 MySQL에서는 사용할 수 있는 것이 없다.
인덱스 알고리즘
키워드의 분석 및 인덱스 구축에는 여러가지 방법이 있을 수 있는데, MySQL 모든 버전에서 기본적으로 제공하는 전문 검색 엔진의 인덱스 방식인 Stopword와 MySQL이 아닌 서드파티에서 제공하는 전문 검색 기능에서의 n-gram가 존재한다.
Stopword
구분자라고도하고 불용어라고도 한다. 일단 전문의 내용을 공백이나 탭 또는 마침표와 같은 문장의 기호, 그리고 사용자가 정의한 문자열을 구분하도록 등록한다. 구분자 기법은 등록된 구분자를 이용해 키워드를 분석해 빼내고, 결과 단어를 인덱스로 생성해두고 검색에 이용하는 방법을 말한다.
일반적으로 공백이나 쉼표 또는 한국어의 조사 등을 구분자로 많이 사용한다. MySQL의 내장 전문 검색 Full Text Search 엔진은 구분자 방식만으로 인덱싱할 수 있다. 구분자 기법은 문서의 본문으로부터 키워드를 추출해 내는 작업이 추가로 필요할 뿐, 내부적으로는 B-Tree 인덱스를 그대로 사용한다.
전문 검색 인덱스의 많은 부분은 B-Tree의 특성을 따르지만 전문 검색 엔진을 통해 조회되는 레코드는 검색어나 본문 내용으로 정렬되어 조회되지는 않는다.
전문 검색에서 결과의 정렬을 일치율이 높은 순으로 출력되는 것이 일반적이다.
추가로 불용어를 추가하고 싶을때는 conf 파일에 설정해돌 수도 있고 innodb에 시스템 변수로도 설정해 놓을 수 있다. innodb 시스템 변수로 등록해두면 다시 mysql을 빌드하지 않아도 적용된다.
n-gram 기법
각 국가의 언어는 띄어쓰기가 전혀 없다거나 문장 기호가 전혀 다른 경우가 허다하다. 이런 다양한 언어에 대해 하나의 규칙을 적용해 키워드를 추출해내기란 쉽지 않으며, 구분자 방식은 추출된 키워드의 일부(키워드의 뒷 부분)만 검색하는 것은 불가능하다는 단점도 존재한다.
이러한 부분을 보완하기 위해서 지정된 규칙 없는 전문도 분석 및 검색을 가능하게 하는 방법이 n-gram 방식이다.
n-gram은 본문을 무조건적으로 몇 글자씩 잘라서 인덱싱하는 방법이다. 트리톤이나 스핑크스와 같은 알고리즘들도 존재하지만 일반적으로 n-gram이 사용이 된다. n-gram에서 n은 인덱싱할 키워드의 최소 글자 혹은 바이트 수를 의미하는데 일반적으로 2글자 단위로 키워드로 쪼개 인덱싱하는 2-Gram or Bi-Gram 방식에 많이 사용된다.
- 문서의 본문을 2글자보다 큰 크기로 블록을 구분해 백엔드 인덱스를 생성
- 백엔드 인덱스의 키워드들을 2글자씩 잘라서 프론트엔드 인덱스 생성
인덱스 검색 과정은 생성과는 반대로 검색어를 2바이트 단위로 동일하게 자른 후 프론트엔드 인덱스를 검색한다. 그 이후 그 결과를 대상 후보군으로 정해 백엔드 인덱스를 통해 최종 검증을해 일치하는 결과를 가져온다.
Stopword vs n-gram
stopword를 사용하여 검색을 하게 된다면 구분자를 기준 삼아 왼쪽 일치 기준으로 비교를 검색하지만 오른쪽 앞에 접두사가 붙어있거나 하는 단어는 검색해내지 못하지만 n-gram은 모든 데이터에 대해 무작위로 N바이트씩 인덱스를 생성하므로 검색이 가능하다.
예를 들어 stopword기법에서 where절에 아이폰을 검색했을때 아이폰 팔아요~ 아이폰 구매해요~ 이런건 검색되지만 애플아이폰 사요! 이런 것은 검색되지 않지만 n-gram은 검색이 된다.
n-gram 방식의 트리톤 전문 검색 엔진과 구분자 방식의 mysql built in 전문 검색 엔진의 성능과 인덱스 크기를 비교해보자, 우선 n-gram 전문 검색 인덱스는 구분자 방식보다 인덱스의 크기가 크다.
n-gram 방식의 인덱스는 인덱스를 생성하는 과정이 복잡해 전문 인덱스에 키워드를 추가하거나 삭제하는 데 시간이 많이 걸리지만, 검색을 수행하는 시간은 2-gram알고리즘의 트리톤이 2~3배 이상 빠르다, 클라이언트의 동시 실행 쿼리수가 많아질 수록 그 차이는 더욱 벌어진다.
가용성
전문 검색 인덱스를 사용하려면 기본적인 비교 연산으로 사용할 수 없고 그에 맞는 구문(함수)를 사용해야한다.
SELECT * FROM tb_test WHERE body LIKE '%애플%';
해당 sql에서는 전문 검색 인덱스가 적용되지 않는다.
전문 검색인덱스를 사용하려면 반드시 MATCH()
AGAINST()
구문으로 검색 쿼리를 작성해야하며, MATCH 절의 괄호에 포함되는 내용은 반드시 전문 검색 인덱스에 정의된 컬럼이 모두 명시돼야한다.
'Computer Science.' 카테고리의 다른 글
TEXT vs VARCHAR [ MySQL ] (24) | 2024.01.08 |
---|---|
VLAN 이해하기 - VLAN, Trunk, Access Port (5) | 2023.10.18 |
TCP 3-way / 4-way Handshake (4) | 2023.10.13 |
gRPC, RPC, 작동원리, HTTP API 비교 (0) | 2023.10.06 |
✍️ 자바 가상머신 JVM 한번에 정복하기 🔥 (0) | 2023.01.19 |