MySQL에서 like 조회는 성능 때문에 잘 사용하지 않는다
현재 개발중인 토이 프로젝트에서 MVP 개발을 위해 검색 API는 추상화하기로 했다. 나중에 시간이 되면 Elasticsearch를 사용하여 검색 API를 마이그레이션 하도록 하고 현재는 간단하게 MySQL의 조회 기능만 사용하도록 할 예정이다.
Like의 성능
다시 본론으로 돌아가서 왜 like 조회는 성능이 잘 나오지 않는다고 주변에서 말할까?
그것은 바로 %
(wild card)가 단어 앞에 붙었을 때 full table scan을 하기 때문이다
MySQL은 단어의 첫번째 문자열로 인덱싱을 하게 된다. B-Tree 인덱스를 활용한 검색은 100% 일치 혹은 값의 *앞부분만 일치하는 경우에 사용할 수 있다. 예를들어 WINAND라는 단어를 검색할 때, WI%로 검색할 때의 범위와 WINA%로 검색할 때의 검색범위가 확연이 차이나게 된다. 첫번째 방법은 W가 첫번째 문자로 들어간 모든 단어를 검색하고, 두번째 방법은 WINA가 들어가는 모든 단어를 검색한다. 전자는 후자보다 더 많은 내용이 검색되게 될 것이다. 즉, WINA는 W보다 더 유니크 하다. 아래의 그림을 보면 바로 이해가 될 것이다.
인덱스에서는 유니크 할 수록 (카디널리티가 높을 수록) 인덱스 속도가 더 빨라지게 된다. 이러한 관점에서 만약 %가 단어의 맨 앞에 붙게되면 full table scan을 하게 된다. 그래서 조회 성능이 좋지 않다고 이야기 하는 것이다.
더 보기
MySQL 5.6 이후 버전에서 Text를 검색하는 기능을 제공한다. VARCHAR, CHAR, TEXT에 대해서만 검색을 할 수 있으나 성능 테스트는 아직 해보지 않았다. Elasticsearch로 마이그레이션 하기 전에 잠깐 테스트 해보는 것이 좋을 것 같다. 해당 내용에 대한 예제는 여기에 잘 나와있으니 추후에 참고해서 개발하면 좋을 것 같다.
참고