문제점
pagination을 하기 위해서 보통 아래와 같은 형식의 쿼리문을 사용한다.
select ... from ... where ... limit ... offset
limit은 가져올 데이터의 총 개수를, offset은 데이터를 조회할 시작점을 의미한다.
여기서 문제는, 데이터 개수가 많아지면(offset 100만건 이상?) offset 위치를 찾는 것을 마치 연결 리스트처럼 처음부터 쭉 이어나가다가 DB에 부하가 크게 걸릴 수 있다.
해결방법
- where절에 조건을 건다.
특정값 이상의 id를 갖는 row만 조회한다던가, 날짜-연도 등을 기준으로 특정일 이후부터만 조회하도록하여 데이터의 개수 자체를 줄여서offset에 드는 부하를 줄여준다.
- covering index를 갖는 subquery를 실행하여 where절에 적용한다.
where절에 subquery를 적용하여 위 방법과 마찬가지로 데이터의 개수를 줄인다. 다만 subquery를 적용할 때, covering index가 적용되도록하여 쿼리 속도에 지장이 없도록 해야한다.
*covering index
select문에서 특정 값들을 조회할 때, composite index에 걸리도록하여 index가 적용되도록 하는 것. 예를 들어 select a, b, c, d from ...같은 쿼리문을 사용한다면 composite index로 a, b, c, d가 생성되어 있는 경우를 의미한다. 만약 이 경우에 a, b, c에 대한 index만 생성되어 있다면 d를 조회할 때는 index를 적용받지 않아서 다시 각 row에 대한 d값을 찾느라 성능이 저하될 수 있다.
참고로 조회 데이터가 충분히 많을 때만 index가 적용된다. 데이터가 적다면 index가 생성되어 있더라도 DB의 쿼리 실행 계획에 따라 자동으로 index를 적용하지 않고 그냥 full scan 할 수도 있다.
추가로 index가 너무 많아지면 index가 차지하는 공간이 많아지고 삽입, 삭제 시 많은 시간이 소요될 수 있다. (B- tree 구조)
'Programming-[Backend] > Database' 카테고리의 다른 글
[경험 요약] Atomikos multi-database transaction 묶기 (0) | 2024.05.04 |
---|---|
[TIL][link] DB Connection Pooling, context manager (0) | 2023.09.18 |
[TIL] insert시 ForeignKey에 제한 걸기: DB Trigger 사용 (2) | 2023.07.23 |
[TIL] 😎 MYSQL 필드 최대 길이 정의 varchar 255 vs 191 (0) | 2023.05.04 |
[TIL] 여러 where 조건 한번에 조회하기. multi column related id query join (0) | 2023.04.03 |