일정 시간동안 n회 이상 인증을 한 로그를 어떻게 남기면 좋을까요? 만약에 1일 이상 지난 데이터들에 대해서 어떻게 무효화 하는 것이 좋을까요? 키 값이 동일한 상황이고, 시간대별로 인증 기록이 남아야 한다면 sorted set도 나쁜 선택이 아닙니다. 스코어를 시간을 하고요. expire를 하는 쪽은 zremrangebyscore 등으로 하는 것도 나쁘지 않은 선택입니다.

 

 이 글에서는 그냥, zremrangebyscore 정도만 이해하는 걸로 해 보도록 하겠습니다.

 


 먼저 test라는 것을 생성하고, score가 0, -1, 2인 데이터를 넣습니다.

 

 

 zrangebyscore로 test의 스코어가 -1이상 2이하인 것을 score랑 같이 조회해 봅시다. 그러면, -1, 0, 2 이렇게 3개가 나옴을 볼 수 있습니다. 만약에 전체를 보고 싶다면 어떻게 하면 좋을까요?

 

 범위에 -inf, inf를 주면 됩니다. 현재 -1, 0, 2 이렇게 3개가 추가되었으니 전체 데이터를 조회했을 때도 sorted set에 3개가 저장되어있음을 볼 수 있어요.

 


 zremrangebyscore는 score 범위에 만족하는 원소들을 제거합니다. 예를 들어, zremrangebyscore test 2 inf를 입력하면, 2 이상인 스코어를 가지는 sorted set test에 있는 것들을 제거합니다. 결과로 1이 나왔는데, 2가 2이상이기 때문에 제거됩니다.

 

 

 제거된 후에 WITHSCORES로 보면, 2개의 아이템 -1과 0이 남아있음을 확인할 수 있습니다. 만약에 전체를 제거하려면 어떻게 하면 될까요?

 

 

 -inf부터 inf까지를 범위로 주면 됩니다. 2개가 제거되었다고 떨어지네요. 다시, zrangebyscore로 조회해 보겠습니다.

 

 empty array가 뜹니다. 그러면 시간 복잡도는 어떻게 될까요?

 


 공식 문서에는 원소 갯수가 n개이고, 삭제할 원소가 m개인 경우에, 삭제할 위치를 찾는 데 걸리는 시간이 O(log(n)), 삭제하는 시간이 O(m)이라고 합니다. 상당히 느리다는 이야기인데요. 당연하게도 원소가 많이 쌓여있으면 그만큼 느립니다.

 

 먼저 sorted set에 800만개의 데이터를 넣았습니다. 그리고, zremrangebyscore로 200만 이상 600만 이하인 데이터를 모두 삭제합니다. 걸린 시간은 1.16초입니다. 만약에 8000만개의 데이터를 넣으면 어떨까요? 그리고 삭제할 원소의 개수가 4000만개이면 어떨까요?

 

 한 번 해보면 되지 않을까요?

 

 18.78초가 걸렸습니다. 약 15배 정도 더 걸린 셈인데요. 이를 토대로 m개의 원소를 삭제하는 데 O(m)보다는 복잡도가 크다는 것을 알 수 있습니다. 데이터가 많이 쌓이면 느려질 수 있다는 것 참고하시면 되겠습니다.