관리자 화면의 상품 검색이 느렸다. 상품명 조건에 LIKE '%키워드%'를 그대로 쓰고 있었다.
Table of contents
Open Table of contents
목표와 제약
검색 응답을 1초 안으로 줄이는 것이 목표였는데, 상품이 이미 300만 건이고 매달 계속 늘어나는 중이었다.
관리자 화면이라 동시 사용자는 적지만 느리면 담당자가 계속 기다린다.
원인 — 앞이 열린 패턴은 인덱스를 못 쓴다
EXPLAIN을 돌려 보니 type: ALL로 전체 스캔이 잡혔다. 상품명에 인덱스가 있는데도 타지 않았다.
B-Tree 인덱스는 앞에서부터 비교하므로 %가 앞에 오면 시작점을 잡을 수 없다.
담당자가 중간 단어로 찾는 경우가 대부분이라 앞의 %를 뺄 수 없었다.
선택지와 대가
방법이 셋이었다. 다른 조건으로 먼저 좁히거나, MySQL 전문 검색을 쓰거나, OpenSearch로 옮기는 것이다.
먼저 좁히는 쪽은 비용이 없는 대신 카테고리를 모르고 검색하는 경우가 절반이다.
MySQL 전문 검색은 추가 비용이 없지만 한글 형태소 분석이 약해서 「무선이어폰」과 「무선 이어폰」이 서로 다르게 잡힌다.
OpenSearch는 검색 품질이 좋은 대신 인스턴스 비용이 늘고 색인 파이프라인을 만들어야 한다.
고른 것과 감수한 것
먼저 좁히는 쪽을 골랐다. 이미 OpenSearch를 다른 용도로 쓰고 있었지만 상품 색인까지 넣으면 인스턴스를 키워야 했다.
등록일 범위를 기본 조건으로 넣고 그 안에서만 LIKE가 돌게 했다. 복합 인덱스는 (등록일, 상품명) 순으로 두었다.
응답이 8초에서 0.6초로 내려갔다. 대신 오래된 상품은 기간을 직접 늘려야 하는 불편을 감수했다.
되돌릴 조건과 적용 범위
기간을 늘려 찾는 비율이 30%를 넘으면 OpenSearch로 옮기기로 정했다. 감수한 불편이 예상보다 크다는 뜻이기 때문이다.
이 방식은 관리자 검색에만 적용했고 고객 검색은 이미 OpenSearch를 탄다.
정리
LIKE '%키워드%'는 앞이 열려 있어 B-Tree 인덱스를 못 탄다- 뒤에만
%가 있으면 인덱스를 탄다 - 다른 조건으로 좁히기·MySQL 전문 검색·OpenSearch 이관 셋을 놓고 봤다
- MySQL 전문 검색은 비용이 없지만 한글 형태소 분석이 약하다
- OpenSearch는 품질이 좋은 대신 인스턴스 비용과 색인 파이프라인이 든다
- 이미 쓰던 OpenSearch도 상품을 넣으려면 인스턴스를 키워야 했다
- 복합 인덱스를
(등록일, 상품명)으로 두어 8초를 0.6초로 줄였다 - 기간을 늘려 찾는 비율이 30%를 넘으면 이 결정을 뒤집는다