2024. 10. 20. 19:46ㆍSpring Boot/Spring Data JPA
데이터베이스에서 대량의 데이터를 처리하는 방식 중 스크롤링(Scrolling)은 데이터를 효율적으로 조회하고 페이지네이션 방식보다 더 세밀한 컨트롤이 가능해 대규모 데이터셋을 다룰 때 유용합니다. 특히 실시간 데이터 처리, 로그 파일 분석, 또는 대규모 레코드 처리 같은 상황에서 유리합니다. 이번 설명에서는 스크롤링의 원리, 주요 유형, 장단점, 그리고 실제 사례를 다루면서 스크롤링의 성능 최적화 및 효과적인 활용 방안을 깊이 있게 살펴보겠습니다.
1. 스크롤링의 개념
스크롤링은 대규모 데이터셋을 한 번에 모두 가져오는 대신, 일정 단위로 분할하여 데이터를 순차적으로 가져오는 기법입니다. 보통 페이지네이션과 혼동되기도 하지만, 스크롤링은 메모리 사용량을 줄이고 성능을 최적화하는 데 중점을 둔 기법입니다.
- 페이지네이션은 페이지 단위로 데이터 집합을 가져오는 방식으로, 주로 UI에서 사용자가 직접 페이지를 넘길 때 쓰입니다. 하지만 페이지 번호에 따라 OFFSET을 사용해 데이터베이스에서 불필요한 데이터를 무시하고 건너뛰는 방식이므로, 큰 OFFSET을 사용할 때 성능이 크게 저하될 수 있습니다.
- 스크롤링은 커서를 사용하여 이전에 가져온 위치를 기억하고, 다음 데이터를 이어서 가져오는 방식으로, 연속적인 데이터 흐름이 중요한 상황에서 자주 사용됩니다.
스크롤링의 주요 장점
- 성능 최적화: 페이지네이션보다 메모리 사용이 적고, 데이터의 특정 위치에 빠르게 접근할 수 있습니다.
- 데이터 일관성: 스크롤링은 새로운 데이터를 계속 추가하거나 변경할 때에도 안정적으로 동작하여, 데이터 일관성을 유지합니다.
2. 스크롤링의 주요 유형
1) 오프셋 기반 스크롤링 (Offset-based Scrolling)
오프셋 기반 스크롤링은 페이지네이션에서 흔히 사용하는 방법입니다. LIMIT
과 OFFSET
을 사용하여 데이터의 특정 범위만큼 가져옵니다. 일반적으로는 간단한 구현이 가능하지만, 많은 양의 데이터를 건너뛰어야 할 때 성능 저하가 발생할 수 있습니다. 대규모 데이터셋에서는 부적합합니다.
예시:
SELECT * FROM orders ORDER BY order_date LIMIT 10 OFFSET 50;
이 쿼리는 51번째부터 60번째까지의 데이터를 가져옵니다.
장점:
- 간단한 구현
- 특정 페이지에 바로 접근 가능
단점:
- 성능 저하: OFFSET이 커질수록 불필요한 데이터를 처리하고 스킵하는 과정에서 성능이 저하됩니다.
- 중복/누락 가능성: 데이터가 동적으로 추가되거나 삭제될 때, 동일한 데이터를 중복 조회하거나 일부 데이터를 누락할 수 있습니다.
2) 키셋 필터링 (Keyset Pagination or Keyset Scrolling)
키셋 기반 스크롤링은 데이터의 고유 키나 인덱스를 기반으로 하여 이전에 조회한 데이터 이후의 데이터를 가져오는 방식입니다. OFFSET
을 사용하지 않기 때문에 성능이 뛰어나며, 특히 대규모 데이터셋에서 효과적입니다. 주로 인덱스나 정렬 가능한 필드가 존재할 때 사용됩니다.
예시:
SELECT * FROM orders WHERE order_date > '2023-01-01' ORDER BY order_date LIMIT 10;
이 쿼리는 2023-01-01
이후의 데이터를 10개 가져옵니다.
장점:
- 대규모 데이터에서 성능 최적화
- 데이터가 동적으로 변경되어도 안정적인 데이터 조회 가능
단점:
- 필드에 인덱스가 존재해야 하며, 특정 순서에 의존하여 데이터를 조회해야 하므로 모든 상황에 적용하기 어려울 수 있습니다.
- 복합 키나 다중 필드 정렬이 필요할 때 구현 복잡성이 증가할 수 있습니다.
3) 커서 기반 스크롤링 (Cursor-based Scrolling)
커서 기반 스크롤링은 데이터베이스 커서를 이용해 데이터를 가져오는 방식으로, 데이터베이스에서 직접 데이터를 하나씩 혹은 일정 범위만큼 읽어오는 방식입니다. 커서를 열고 데이터베이스에서 한 번에 처리할 수 없는 대규모 결과를 순차적으로 가져오는 방식입니다.
예시:
DECLARE user_cursor CURSOR FOR
SELECT * FROM users ORDER BY lastname;
커서로 데이터를 순차적으로 조회하고 필요할 때마다 닫을 수 있습니다.
장점:
- 메모리 효율성: 데이터 전체를 로드하지 않고, 필요할 때마다 가져오므로 메모리 사용량을 최소화할 수 있습니다.
- 실시간 대규모 데이터 처리에 적합
단점:
- 커서를 오랫동안 열어 두면 데이터베이스 리소스를 차지하므로 리소스 관리에 신경 써야 합니다.
- 커서를 사용한 쿼리는 데이터베이스마다 다르게 지원될 수 있으며, 구현이 복잡할 수 있습니다.
4) 윈도우 스크롤링 (Windowing)
윈도우 스크롤링은 정렬된 데이터를 일정 크기로 분할하여 가져오는 방식입니다. 주로 사용자가 지정한 크기(윈도우)로 데이터를 조회하며, 페이징처럼 구간별로 데이터에 접근할 수 있습니다.
예시:
SELECT * FROM orders ORDER BY order_date ROWS BETWEEN 10 PRECEDING AND 10 FOLLOWING;
이 쿼리는 특정 기준을 중심으로 일정 범위의 데이터를 조회합니다.
장점:
- 데이터를 유연하게 조회할 수 있음
- 복잡한 연산을 지원 (예: 이동 평균)
단점:
- 오프셋 기반과 비슷한 성능 문제를 가질 수 있음
- 복잡한 쿼리와 인덱스가 필요함
3. Spring Data JPA에서의 스크롤링
Spring Data JPA에서는 스크롤링을 다양한 방식으로 지원하며, 주로 PagingAndSortingRepository
나 Streamable
과 같은 인터페이스를 통해 구현할 수 있습니다.
1) 오프셋 기반 스크롤링 (Offset Scroll)
interface OrderRepository extends PagingAndSortingRepository<Order, Long> {
Page<Order> findByOrderDateAfter(Date date, Pageable pageable);
}
Page<Order> orders = orderRepository.findByOrderDateAfter(startDate, PageRequest.of(0, 10));
while (!orders.isEmpty()) {
for (Order order : orders) {
// 각 주문 처리
}
orders = orderRepository.findByOrderDateAfter(startDate, orders.nextPageable());
}
2) Keyset 기반 스크롤링 (Keyset Scroll)
interface OrderRepository extends JpaRepository<Order, Long> {
List<Order> findFirst10ByOrderDateAfterOrderByOrderDateAsc(Date date);
}
Date lastDate = startDate;
List<Order> orders;
do {
orders = orderRepository.findFirst10ByOrderDateAfterOrderByOrderDateAsc(lastDate);
for (Order order : orders) {
lastDate = order.getOrderDate(); // 마지막으로 처리된 주문의 날짜를 저장
}
} while (!orders.isEmpty());
3) Streamable 기반 스크롤링
Streamable<Order> orders = orderRepository.findAll();
orders.forEach(order -> {
// 각 주문 처리
});
4. 스크롤링 성능 최적화
인덱스 활용
대규모 데이터에서 스크롤링 성능을 극대화하려면, 자주 검색되는 필드에 적절한 인덱스를 설정해야 합니다. 특히 키셋 기반 스크롤링은 인덱스 성능에 크게 의존하므로 반드시 인덱스를 고려해야 합니다.
쿼리 최적화
불필요한 데이터 로드를 방지하기 위해, 조회하고자 하는 필드만 선택적으로 가져오도록 쿼리를 최적화해야 합니다. 예를 들어, SELECT *
대신 필요한 컬럼만 명시하여 조회합니다.
5. 스크롤링의 장단점 요약
장점:
- 메모리 효율성: 대규모 데이터를 한 번에 가져오지 않으므로 메모리 사용량이 낮습니다.
- 성능 향상: 키셋 기반 스크롤링과 같은 방법은 페이지네이션보다 더 나은 성능을 제공합니다.
- 대규모 데이터 처리: 실시간으로 대량의 데이터를 다루는 데 적합합니다.
단점:
- 복잡성 증가: 특히 키셋 기반 또는 커서 기반 스크롤링은 단순 페이징보다 구현이 복잡할 수 있습니다.
- 리소스 관리: 커서를 사용하는 경우 오랜 시간 동안 커서를 유지하면 데이터베이스 리소스가 많이 소모될 수 있습니다.
스크롤링은 특히 대규모 데이터셋을 다루는 데 있어 중요한 데이터 처리 기법입니다. 각 유형의 스크롤링 방법은 상황에 따라 선택적으로 사용될 수 있으며, 성능 최적화와 데이터 일관성을 유지하는 데 큰 역할을 합니다.
'Spring Boot > Spring Data JPA' 카테고리의 다른 글
Transactionality (0) | 2024.10.22 |
---|---|
Projections (0) | 2024.10.22 |
Configuring Fetch- and LoadGraphs (0) | 2024.10.20 |
Applying Query Hints (0) | 2024.10.20 |
Other Methods, Modifying Queries (0) | 2024.10.20 |