📌 Full‑Text Index (풀텍스트 인덱스) 란?
일반적인 텍스트 검색(LIKE '%텍스트%')은 테이블 풀스캔(full scan) 을 유발해 데이터가 많아질수록 속도가 크게 떨어집니다. Full‑Text Index는 이런 문제를 해결하기 위해 텍스트 전체를 대상으로 인덱스를 생성하고, 이를 이용해 빠르게 검색할 수 있도록 해 줍니다.
- char / varchar / text 타입 컬럼에 적용 가능
- InnoDB / MyISAM 엔진에서 지원됨
- 여러 컬럼에 중복 적용 가능
- db버전을 반드시 확인해주도록 합니다.
- MySQL : MyISAM엔진에서는 기본지원, InnoDB에서는 5.6버전 이상부터 지원
- MariaDB : 버전10 InnoDB에서 기본지원
💡 Full‑Text Index 생성
인덱스는 테이블 생성 시 또는 기존 테이블에 추가할 수 있습니다.
인덱스를 수정해야 한다면 삭제 후 생성해줍니다.
인덱스 생성하게되면 analyze를 꼭 실행하도록 합니다.
-- 테이블 생성 시
CREATE TABLE MyTbl (
id INT PRIMARY KEY,
content TEXT,
FULLTEXT (content)
);
-- 기존 테이블에 추가
ALTER TABLE MyTbl ADD FULLTEXT (content);
-- 별도 인덱스 생성
CREATE FULLTEXT INDEX idx_content ON MyTbl (content);
-- 인덱스 확인
SHOW INDEX FROM MyTbl;
🔍 Full‑Text 검색 방법
Full‑Text 검색은 일반적인 WHERE LIKE 대신 MATCH() … AGAINST() 문법을 사용해야 인덱스가 활용됩니다.
🧠 1) 자연어 검색 (Natural Language Mode)
- 특별히 옵션을 지정하지 않거나 뒤에 in natural language mode를 붙이면 자연어 검색을 합니다.
- 자연어 검색은 단어가 정확한 것을 검색해줍니다.
SELECT * FROM MyTbl WHERE MATCH(content) AGAINST('검색어');
SELECT * FROM MyTbl WHERE MATCH(content) AGAINST('검색어' in natural language mode);
SELECT * FROM MyTbl WHERE MATCH(content) AGAINST('검색1 검색2');
-- ‘검색1’ 또는 ‘검색2’ 두 단어 중 하나가 정확히 포함된 content 검색
⚙️ 2) 불린 모드 검색 (Boolean Mode)
- LIKE연산자에서 %를 쓰듯이 불린 모드 검색기능을 사용할 수 있습니다.
- 단어나 문장이 정확히 일치하지 않는 것도 검색할 수 있습니다.
- 뒤에 in boolean mode 옵션을 붙여주면 적용됩니다.
- 검색 단어 간 조합, 필수 포함, 제외, 와일드카드 등을 설정할 수 있습니다.
- 연산자의미
+ 반드시 포함 - 포함하지 않음 * 와일드카드 (뒤에만 사용) " 정확 구문 검색 ~ 부정적인 기여 (순위 낮춤)
SELECT * FROM MyTbl
WHERE MATCH(content) AGAINST('검색일 +검색이' IN BOOLEAN MODE);
-- '검색일'을 찾되 반드시 '검색이'가 들어가 있는 데이터
SELECT * FROM MyTbl
WHERE MATCH(content) AGAINST('검색일 -검색이' IN BOOLEAN MODE);
-- '검색일'을 찾되 '검색이'는 안들어가 있는 데이터
SELECT * FROM MyTbl
WHERE MATCH(content) AGAINST('검색일 ~검색이' IN BOOLEAN MODE);
-- ‘검색일’을 찾되 ‘검색이’가 없는 열보다 ‘검색이’가 있는 열이 아래 순위
SELECT * FROM MyTbl
WHERE MATCH(content) AGAINST('검색*' IN BOOLEAN MODE);
-- ‘검색을’, ‘검색이’, ‘검색은’ 등 모두 검색
SELECT * FROM MyTbl
WHERE MATCH(content) AGAINST("유익한 검색" IN BOOLEAN MODE);
-- “유익한 검색”, “유익한 검색이” 등
-- “유익한 한국어 검색”, “유익한 영어 검색” 불가
✨ 3) 쿼리 확장 검색 (WITH QUERY EXPANSION)
- 자연어 모드 기반, 검색 결과에서 연관 단어를 추출하여 재검색 합니다.
- 첫 단계에서는 자연어 검색을 수행, 첫 번째 검색의 결과에 매칭된 행을 기반으로 검색 문자열 재구성 하여 두번째 검색 수행
- 1단계 검색에서 사용한 단어와 연관성이 있는 단어가 1단계 검색에 매칭된 결과에 나타난다는 가정을 전제로 한다.
🔹 최소 토큰 길이 (Minimum Token Size)
- FULLTEXT 인덱스는 기본적으로 일정 길이 이상의 단어만 인덱싱합니다.
- MySQL / MariaDB 기본값
- MyISAM: ft_min_word_len = 4 (기본 4글자 이상)
- InnoDB: innodb_ft_min_token_size = 3 (기본 3글자 이상)
- 즉, 2글자의 단어는 인덱싱을 하지 않습니다.
- 조정 방법:
- 만약 조정이 필요하다면 설정 변경 후 FULLTEXT 인덱스 재생성이 필요합니다.
-- 몇 글자 이상부터 검색 가능한지 확인
SHOW VARIABLES LIKE 'innodb_ft_min_token_size';
조정 필요할경우 my.ini 수정
innodb_ft_min_token_size=2
여기부터는 심화내용 입니다 :D
🧩 4) 파서(Parser)와 Stopword 처리
- 파서(Parser): 텍스트를 단어 단위로 쪼개고, 인덱스를 생성하는 핵심 기능
- 토큰화, Stopword 적용, 형태소 분석, 인덱스 생성
- Stopword 란?
- 검색 시 무시되는 단어를 의미합니다.
- 인덱스에 포함되지 않고 검색 결과에 영향을 거의 주지 않는 단어를 말합니다.
- 예 ) the, a, of, is / 은, 는, 이, 가, 의
- Stopword 적용하려면 최소한 단어 단위로 텍스트를 분리할 수 있는 파서( N-gram , MeCab 등)이 필요합니다.
- 주의 : MariaDB는 N-gram 파서 미지원
- MariaDB의 경우 LIKE검색과 같이 써야한다
- 예 ) MATCH(content) AGAINST(CONCAT('+검색*') IN BOOLEAN MODE)
OR content LIKE CONCAT('%검색%')
[ 전체 텍스트 인덱스 단어 확인 ]
--db와 테이블 이름은 소문자 써야된다.
set global innodb_ft_aux_table = '디비명/테이블명';
--테이블에서 만들어진 전체텍스트 인덱스 보기 (필요없는 검색 단어가 있음)
select word, doc_count, doc_id, position from information_schema.innodb_ft_index_table ;
-- 중지단어 만들기전에 만들어놓은 풀텍스트 인덱스는 삭제
drop index idx_all on FulltextTbl ;
-- 중지단어를 위한 테이블 만들기
-- 테이블의 데이터는 반드시 value , 타입은 varchar
CREATE TABLE user_stopword (value VARCHAR(30));
--중지 단어 만들기
insert into user_stopword values ('그는'), ('그리고'), ('후에') ;
-- 중지 단어 테이블에 지금 만들 테이블을 추가하는 작업
-- 그러면 이제 user_stopword 테이블에 들어있는 단어로는 풀텍스트 인덱스를 만들지 않게 된다
set global innodb_ft_server_stopword_table = '디비명/user_stopword';
-- 만든 테이블이 들어갔는지 확인
show global variables like 'innodb_ft_server_stopword_table' ;
-- 중지단어 테이블 만들었으니, 이제 다시 풀텍스트 인덱스 생성.
create Fulltext index idx_description on FulltextTbl ( description );
-- 그러면 중지단어에 등록한 단어를 제외한 인덱스 단어들이 생성됨 (갯수가 줄어들음)
select word, doc_count, doc_id, position from information_schema.innodb_ft_index_table ;
[MYSQL] 📚 풀텍스트 인덱스(Full-Text Index) 사용법
보통 mysql 에서 텍스트 문자열을 검색시 like 나 instr 연산자를 사용해 원하는 텍스트를 필터링하여 조회할 수 있다. SELECT * FROM FulltextTbl WHERE description LIKE '%남자%'; -- 중간에 남자 들어간 글 검색
inpa.tistory.com
https://dogcowking.tistory.com/78
MySQL Full-Text 검색 / match against
- 180123 내용 보완 * MySQL 에서 텍스트 검색시 like '%XXX'%' 나 REGEXP 이용 가능하지만데이터가 늘어나면서 성능이 떨어짐- 미리 Fulltext Index 를 만들어 놓아 빠른 검색 가능- MyISAM엔진 에서는 기본 지원
dogcowking.tistory.com
'잡지식' 카테고리의 다른 글
| [ django ] 괜히 쓸모있었던 블로그 포스팅들 (0) | 2021.01.18 |
|---|---|
| JAVA JDBC/DBCP/JNDI (0) | 2017.06.06 |
| 스크립트 단에서 쿠키제어 (0) | 2017.02.24 |
| java string 문자열에서 숫자인지 문자인지 분류 (0) | 2016.05.25 |