최근 프로젝트에서 Elasticsearch(ES)와 MySQL을 활용하여 여러 API의 성능을 비교해본 결과, 의외로 MySQL 기반 쿼리가 ES 기반 쿼리보다 더 빠르게 동작하는 현상을 발견했다.보통 ES는 대규모 데이터 검색과 복잡한 쿼리를 처리하는 데 최적화된 도구로 알려져 있는데, 왜 이런 결과가 나왔을까?
확인할 것:
ES와 MySQL에서 처리 중인 데이터의 양과 쿼리 복잡성.
ES의 인덱스 매핑이 적절히 설정되어 있는지 확인.
테스트 환경
Elasticsearch: Docker를 통해 설치, 데이터 인덱싱 후 검색 테스트.
MySQL: 동일 데이터로 쿼리 성능 테스트.
API 비교:
- ES 관련 API: /search/keyword, /admin/search
- MySQL 관련 API: /search/filter, /search/reservations
테스트 결과 (Grafana 데이터 시각화)
Elasticsearch API 응답 시간:
- /search/keyword: 평균 0.00772초
- /admin/search: 평균 0.00407초
MySQL API 응답 시간:
- /search/filter: 평균 0.00436초
- /search/reservations: 평균 0.00179초
결과적으로, MySQL 기반 쿼리가 ES 기반 검색보다 2배 이상 빠른 경우도 있음을 확인했습니다.
Elasticsearch가 더 느린 이유를 chatgpt에 물어봤다. 지피티는 다음과 같이 대답해줬다.
(1) 데이터 크기와 복잡성
Elasticsearch는 대규모 데이터를 처리하고 복잡한 검색 조건에서 강점을 발휘합니다. 하지만 소규모 데이터나 단순 조건의 검색에서는 초기 오버헤드가 발생할 수 있습니다.
MySQL은 단순 검색이나 적은 데이터 처리에서 빠른 응답성을 보일 수 있습니다.
(2) Elasticsearch 인덱싱 구조
Elasticsearch는 데이터를 검색하기 전에 인덱싱 과정을 거칩니다. 이 과정에서 데이터를 분석하고 분산 저장하기 때문에 MySQL보다 더 많은 리소스를 소비합니다.
적절한 인덱스 매핑(mapping)이나 refresh_interval 설정이 없으면 성능이 저하될 수 있습니다.
(3) 쿼리 최적화 문제
Elasticsearch 쿼리가 비효율적으로 작성되었거나 불필요한 필드까지 검색하고 있을 가능성이 있습니다.
반면, MySQL은 인덱스를 적절히 활용해 쿼리를 최적화했다면 더 빠를 수 있습니다.
(4) 네트워크 지연
Elasticsearch는 Docker 환경에서 실행되고 있었는데, Docker 리소스 제한이나 네트워크 지연으로 인해 성능 저하가 발생했을 가능성이 있습니다.
(5) 캐싱 효과
MySQL은 쿼리 캐싱이 기본적으로 활성화된 반면, Elasticsearch의 캐싱은 명시적으로 설정하지 않으면 비활성 상태일 수 있습니다.
(1) Elasticsearch 쿼리 및 인덱스 최적화
쿼리 최적화:
불필요한 필드를 검색하지 않도록 쿼리를 정제합니다.
explain API를 사용해 쿼리 실행 계획을 분석하세요.
인덱스 매핑 개선:
검색에 필요한 필드만 인덱싱하도록 매핑을 간소화합니다.
텍스트 분석이 필요 없는 필드는 keyword 타입으로 설정합니다.
(2) Elasticsearch 설정 확인
refresh_interval 설정:
실시간성이 낮아도 되는 데이터라면 refresh_interval을 늘려 검색 부하를 줄일 수 있습니다.
Docker 리소스 할당:
Docker 컨테이너에 충분한 메모리와 CPU를 할당합니다.
Elasticsearch가 실행 중인 하드웨어 리소스와 네트워크 상태를 점검합니다.
(3) MySQL과 Elasticsearch의 역할 분리
단순 검색(필터링, 정렬 중심)은 MySQL에 맡기고, 복잡한 검색(키워드 기반 검색, 범위 검색 등)은 Elasticsearch를 활용합니다.
(4) 네트워크 성능 최적화
Elasticsearch와 MySQL 서버 간 네트워크 지연을 확인하고 최적화합니다.
(5) 캐싱 활성화
Elasticsearch에서 쿼리 캐싱을 활성화하여 자주 실행되는 쿼리의 성능을 높입니다.
프로젝트 끝나면 이 부분을 수정하거나, 대용량 데이터를 사용해서 제대로 테스트 해보고 싶다.