본문 바로가기
프로젝트/개인 프로젝트(2023.11.13-2023.12.18)

[개인프로젝트] ElasticSearch와 Mysql 쿼리 실행시간 (2) (인덱스 걸기)

by dal_been 2024. 2. 19.
728x90

이전블로그에서 mysql 인덱스 안걸려있고 full scan으로 했으때의 elasticsearch와의 검색 실행시간 차이를 알아보았다.

이번에는 mysql에 인덱스를 걸었을때의 상황을 비교해보겠다.

 


간단하게 데이터베이스에서의 인덱스란 미리 정렬된 정보를 저장하여, 원하는 데이터를 찾는 것이다.

즉 검색 속도를 향상시킬 수 있다. 이부분에 대해서 추후 더 자세하게 알아볼 예정이다.

 

일단 실행시간 보기전에 알려드릴점...

첫번째원래 이전 블로그에서는 distance가  3km였는데 0.5km로 바꾸었다. 그 이유는 mysql이 인덱스를 타지 않고 full scan을 해서이다. 20만개 데이터중 쿼리를 나리면 2/3이상의 데이터가 결과값으로 나오다보니 full scan을 타버렸다. 그래서 인덱스를 타기 위해 범위를 좁혔다.

 

두번째 mysql쿼리가 조금 다르다. 이전 블로그의 st_distance_...는 인덱스를 타지 않는다고 한다. 그래서 "ST_CONTAINS((ST_Buffer(ST_PointFromText" 형태로 바꾸었다. 형태로 바꾸었더니 탐색범위에서도 차이가 나서 쿼리 개수가 다르다. 

 

 

ElasticSearch 실행시간

 

GET walkers/_search 
 {"from":0,"post_filter":
    {"geo_distance":
        {"location":{"lat":37.3051481995,"lon":127.06808991948147},"distance":"0.5km","distance_type":"plane"}},
    "query":
        {"bool":
          {"must":
            [{"query_string":
               {"analyze_wildcard":true,
               "fields":["walker_name"],"query":"*tast19*"}
              
            }]}},
  "size":10,"track_scores":false,"version":true
 }

 

1 65ms
2 50ms
3 48ms
4 41ms
5 24ms
6 36ms
7 72ms
8 74ms
9 55ms
10 25ms

 

총 20만개의 데이터중 원하는 값을 size = 10 기준으로 찾는데 평균 49ms가 걸린다.

 

 

Mysql 인덱스 걸었을때

 

인덱스가 걸렸음을 확인

 

1 80ms
2 80ms
3 79ms
4 79ms
5 81ms
6 80ms
7 88ms
8 87ms
9 86ms
10 86ms

 

총 20만개의 데이터중 원하는 값을 size = 10 기준으로 찾는데 평균 82.6ms가 걸린다.

 

 

ElasticSeach가 약 1.6배 더빠르다.

인덱스 없이 쿼리를 날렸을때는 

SELECT ST_CONTAINS ((ST_Buffer(ST_PointFromText('POINT(37.30594819955 127.06708991948)', 4326), 500)), users.location)
        FROM users IGNORE INDEX(idx_coordinated)
WHERE ST_CONTAINS ((ST_Buffer(ST_PointFromText('POINT(37.30594819955 127.06708991948)', 4326), 500)), users.location)
  AND users.user_name like '%test8%'
ORDER BY
    distance
    LIMIT 0,10

 

평균 180ms가 나왔다.

따라서 인덱스를 걸은 mysql 쿼리가 약 2.1배 빠르다.!

 


ElasticSearch, 인덱스 안걸은 mysql , 인덱스 걸은 mysql 셋을 비교해보았다.

 

먄약 누군가 elasticsearch 사용에 고민하고 있다면 ... 이부분을 고려해봤으면 좋겠다.

 

1. elasticsearch를 ec2에 설치한 docker에서 실행하면 생각보다 프리티어 서버에 부하가 많이 된다

-> 협업프로젝트때 팀원분이 elasticsearch를 통해 검색을 구현하셨는데 elasticsearch랑 kibana키자마자 서버가 다운되더라...

다행히 kibana안키고 elasticsearch만 키면 돌아가긴하는데.. 이러면 elasticsearch가 잘돌아가는지 알 수 없으니..

 

2. elasticsearch에 이전 데이터를 넣을때 시간이 많이 걸린다.

-> 나의 경우 테스트를 위해 20만개 데이터를 elasticsearch에 넣을때 30분이 걸렸다..

 

3. elasticsearch는 실시간 처리가 불가능하다

-> elasticsearch는 인메모리 버퍼를 사용하므로 쓰기와 동시에 읽기 작업을 할 경우, 세그먼트가 생성되기 전까지는 해당 데이터를 검색할 수 없다.

 

4. elasticsearch는 업데이트가 애매하다..?

-> elasticsearch의 경우 데이터를 업데이트 하는 것이 수정하는게 아니라 삭제했다가 새롭게 데이터를 넣는 것이다.

그러다보니 만약 전체적으로 한 필드의 값을 수정해야하는 경우 삭제 -> 새로운 데이터 삽입 으로 해야하기때문에 시간이 오래걸린다.

(앞서 이야기했듯이 20만개 데이터 삽입에만 30분이 걸렸다..)

 

5. 관리해야할 부분이 생긴다..

-> elasticsearch의 경우 db를 하나 더 관리해야한다는 느낌이 든다. 왜냐하면 협업프로젝트때 배포할때마다 서버가 감담을 하지 못해 가끔 elasticsearch의 document가 다운될때가 있었다. 그럴때마다 검색이 안되서.. 프론트분들이 이거 안된다고.. 말씀을 아주 자주 하셨다. 물론 서버 자체가 프리티어이기에 다운된 거일 수 도 있지만 어째든 데이터를 관리해야한다는 점과 서버 쪽에서도 부하가 생기지 않는지 계속 신경써야한다.