규턴의 개발블로그
article thumbnail

 

이번 소프티어 부트캠프를 하면서 주유소 검색 기능을 추가해야 했었다

 

사용자가 입력하는 주유소 이름을 기반으로 18000개의 데이터를 full scan 해야 하는 상황..

 

저희는 당연히 redis가 더 빠를것이라 생각해서 redis에 주유소 정보를 모두 저장하였다.

 

구조는 다음과 같다.

 

 

 

 

 즉 12000개의 주유소의 PK가 Key값으로 저장되고 해당 key는 Object로 GasStation정보를 가지고 있다.

 

 

Redis로 주유소를 검색하는 경우

 

 

 

요청 받은 이름이 포함되어 있는것은 List에 add 하여 요청이름이 포함되는 주유소 리스틀 보여주는 과정을 API 구축을 하였다.

 

 

 

 

full scan 했을때 3분이 걸렸다.. ㅋㅋㅋㅋㅋ

 

 

DB(MYSQL)로 주유소를 검색하는 경우

 

0.3초가 걸렸다..

 

 

결론 왜 이럴까?

 

원래 대부분이 생각하기에는 Redis에서 데이터를 꺼내오는 작업이 빠르다고 생각을 한다. 하지만 , 이건 redis의 키값을 사용했을때 빠른경우이다.

 

그러면 왜이럴까?

 

1. 레디스는 결국 근본적으로 Key, Value로 되어 있고 Key값으로 빠르게 찾는것에 특화되어 있는데 나는 Key값을 사용하지 않는다.

 

2. 내가 쓴 코드는 Redis의 모든 데이터를 FindAll해서 가져오고 결국 Contains를 사용해야만 하는 코드이다. 즉 접근방법이 잘못된 코드일 수 있다.(하지만 위의 DB접근에도 select * from gasStation을 한 후 Java단에서 contains를 했었다.)

 

3. findAll메서드는 결국 redis의 scan명령어를 사용한다. 그리고 scan을 하면서 얻은 객체를 Java Object로 매핑하여 return한다. 해당 과정이 시간을 많이 잡아 먹는 과정일 수 있다.(DB보다 더 오래 걸릴 수 있다.)

 

4. Redis와 MYSQL의 자료구조에서 오는 차이

 

 

  1. Data size: Depending on the amount of data you have stored in Redis, retrieving all the keys using redisDao.findAll() could be slower than retrieving all the rows from a table in a database. Redis is an in-memory database, and if you have a large dataset, it may take longer to retrieve all the keys from memory than to read all the rows from disk in a traditional database.
  2. Data structure: Redis and databases like MySQL store data in different ways. Redis is optimized for fast data access and retrieval, especially for small data structures like key-value pairs, lists, and sets. However, if your data is stored in a more complex structure like a hash or a sorted set, retrieving all the keys and values using redisDao.findAll() could be slower than retrieving all the rows from a table in a database.


실제 chatGpt에서도 내가 생각한 비슷한 답변을 하고 있다.

 

간단하게 요약하면 다음과 같다.

1. 데이터사이즈가 크면 DB가 더 빠를 수 있다.(우리가 테스트한 DB는 1만개 이상)

 

2. 저장하는방식(자료구조에서 오는차이): 단지 key,value가 아닌 hash구조로 된 값을 찾을때 더 오래 걸릴 수 있다고 한다.

 

 

실제로 FullScan을 해서 redis에서 가져오는것보다 DB를 FullScan을 사용하는게 더 빨랐다..

 

 

즉, redis의 키값을 이용해 접근하는 방법은 DB보다 빠를 수 있어도 full scan의 경우에는 느릴 수 있다..

 

 

그러면 어떻게?

 

그러면 이제 남은 선택지는 두가지가 있다(ELASTIC SEARCH는 사용법이 미숙해서 패스... 검색기능에서는 최강이라고 하긴함)

 

1. select * from gasStation이후 java의 String.contains를 활용하기

2. SELECT * FROM gas_stations WHERE name LIKE '%gas%';와 같이 like절을 사용해 가져오기

 

 

확실히 contains를 하는것보다 query를 작성하는것이 더 빠르다..

 

찾아보니 자바의 contains를 사용하는것 보다 쿼리를 작성하는것이 더 빠르다고 한다.

 

그 이유는 여러가지 이유(DB자료구조와 like절과 contains로직의 차이점)가 있겠지만 인덱싱!도 하나의 요소가 될 수 있다.

 

인덱싱을 통해 사용자의 요청 이름이 포함된 이름을 찾는것을 더 빠르게 할 수 있다고 한다.

 

추후 테스트해보고 해당 결과를 남길까 한다.

 

 

참고하면 좋은 자료

https://jjjwodls.github.io/spring/2020/01/06/02-Redis-Performance.html

profile

규턴의 개발블로그

@규턴이

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!