도입배경
- JPA를 이용해 검색 기능을 구현했지만, 대량의 레코드에서 검색 시간이 오래걸리는 문제가 발생하였습니다.
- Native Query와 Full Text Index를 활용하여 검색 성능을 개선할 수 있다는것을 알게되습니다.
- 직접 코드를 구현하여 성능일 비교하고, 프로젝트에 적용해보았습니다.
Full Text Index를 사용하는 이유
- Full Text Index는 텍스트 기반 데이터의 검색 속도를 높이기 위한 인덱스 방식입니다.
- 특히 긴 문자열에서 특정 단어를 빠르게 찾기 위해 사용되며, 검색 대상이 되는 데이터가 크고 복잡할수록 성능 향상이 두드러집니다.
- 한국어는 영어와 달리 단어별로 명확한 띄어쓰기가 없어 검색 성능 향상이 쉽지 않지만, MySQL의 n-gram parser를 이용해 이를 보완할 수 있습니다.
- n-gram parser는 문자열을 일정 길이(기본값: 2글자)로 분할하여 토큰으로 저장해 인덱스를 생성하며, 이로 인해 긴 텍스트에서도 원하는 단어를 빠르게 찾을 수 있습니다.
MySQL에서 Full Text Index 생성하기
1. 생성 SQL 문
Full Text Index는 일반적인 인덱스와 유사하게 SQL로 생성할 수 있으며, WITH PARSER ngram 구문을 통해 n-gram parser로 인덱스를 생성할 수 있습니다.
아래 예시는 소설의 제목을 대상으로 Full Text Index를 생성하는 코드입니다.
CREATE FULLTEXT INDEX ft_index_title_description ON novel (title) WITH PARSER ngram;
2. 인덱스 조회 SQL 문
- 생성된 인덱스가 실제로 적용되는지 확인하기 위해 두 가지 방법을 사용할 수 있습니다.
1) EXPLAIN 명령어
- EXPLAIN 명령어로 실행 계획을 확인하여, 생성한 INDEX가 실제로 적용되는지 검증 할 수 있습니다.
- 결과적으로 SELECT 문 실행 시 생성한 Full Text Index가 정상적으로 적용되는 것을 확인할 수 있었습니다.
EXPLAIN SELECT *
FROM novel
WHERE MATCH(title) AGAINST('검색어');

2) 시스템 변수 이용
- MySQL에서는 innodb_ft_aux_table 시스템 변수를 사용해 특정 테이블의 Full Text Index 정보를 자세히 확인할 수 있습니다.
- information_schema.INNODB_FT_INDEX_TABLE 테이블을 통해 인덱스에 포함된 토큰과 각 토큰이 몇 개의 레코드에 등장하는지 조회할 수 있습니다.
- 이 설정은 글로벌 변수이므로 테스트 시에만 활성화해야 합니다.
SET GLOBAL innodb_ft_aux_table = 'netnovel/novel';
SELECT *
FROM information_schema.INNODB_FT_INDEX_TABLE;

결론
- 이번 포스트에서는 대용량 텍스트 데이터를 효과적으로 검색하기 위해 MySQL에서 Full Text Index를 사용하는 이유와 생성 및 검증 방법을 다루었습니다.
- 다음 포스트에서는 이 인덱스를 활용하여 JPA와 Native Query로 조회하는 방법과 그 성능을 비교해 보겠습니다.
'Spring' 카테고리의 다른 글
[Spring] OAuth2 기반 회원 인증 시스템 도입 (1) - 도입배경,이론 (1) | 2024.11.07 |
---|---|
[Spring] Full-Text Index를 활용한 DB 검색 성능 최적화 (2) - Spring 코드 구현, 성능 비교 테스트 (1) | 2024.11.06 |
[Spring] Redis 기반 세션 스토리지 구축 (3)- Redis vs MySQL 성능비교 (0) | 2024.11.01 |
[Spring] Redis 기반 세션 스토리지 구축 (2)- 구현 (1) | 2024.11.01 |
[Spring] Redis 기반 세션 스토리지 구축 (1)- 도입배경, 설계 (0) | 2024.10.30 |