강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

황은경님의 프로필 이미지
황은경

작성한 질문수

스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판

게시글 목록 API - 페이지 번호 - N번 페이지 M개 게시글 - 설계

OFFSET 기반 페이지네이션에서 인덱스를 활용한 성능 최적화 방식과 실제 테이블 접근 시점이 궁금합니다

해결된 질문

작성

·

130

0

안녕하세요 좋은 강의 감사드립니다~

게시글 목록 조회시

select * from article

where board_id = 1

order by article_id desc

limit 30 offset 1499970;

1.여기 쿼리문에서 where 절이 먼저 실행되어 (board_id, article_id) 생성된 secondary Index 에서 board_id = 1 인 데이터들을 찾아서

2.어차피 article_id 도 정렬이 되어 있으니 이 부분에서 offset 을 순차적으로 skip 하면서 결국에 마지막에

3.select * 문을 수행하는게 아닌가요?

2번 과정에서 order by article_id 를 위해 clusterd Index 에서 데이터를 조회하는 과정이 추가되나요?

> 게시글 목록 API - 페이지 번호 기반 - N번 페이지, M개 게시글 - 설계

> 20:07

마지막에 최종적으로 select * 문을 조회할때만 clusterd Index 에서 데이터를 조회하는거 아닌가요? 왜냐하면 이미

secondary Index 에서 article_id 가 정렬되어 있기 때문에 그냥 skip 하고 마지막에만 clusterd Index 에서 데이터를 조회할 것 같습니다.

답변 2

3

쿠케님의 프로필 이미지
쿠케
지식공유자

은경님, 안녕하세요!

일단 강의 잘 수강해주셔서 감사합니다!

 

스킵하는 과정에 대해 세컨더리 인덱스만 태울 수 있으면 좋겠지만, 현재는 클러스터드 인덱스도 반드시 거쳐가고 있습니다.

그렇기 때문에 offset이 커질수록 스킵하는 비용도 커지다보니 성능 이슈가 발생하게 되는 것이고요.

 

그렇다면, 세컨더리 인덱스만 타도 충분한 상황에, 왜 항상 클러스터드 인덱스만 타는지 궁금하실 수 있을 것 같습니다.

InnoDB의 동작이 왜 이렇게 만들어졌냐고 묻는다면..

사실 제가 데이터베이스 개발자는 아니다보니, 이러한 설계 방향에 대해서까지 명쾌하게 답변 드리긴 쉽지 않네요.. ㅎㅎㅎ

이론 상 가능하긴 하지만, 설계 일관성 측면에서 특정 케이스에 대해서만 최적화하기에는 어려움이 있지 않았을까 싶기도 합니다.

 

이전에도 다른 분도 유사한 질문을 주신 적이 있는데요,

제대로 된 답변을 드리진 못 했었지만.. 참고 정도로만 살펴보셔도 좋을 것 같습니다!

https://inf.run/TYeHA

0

안녕하세요, 인프런 AI 인턴입니다. 황은경님.

질문하신 OFFSET 기반의 페이징 쿼리에서 인덱스를 어떻게 활용하는지 설명드리겠습니다. 이 쿼리는 데이터베이스 성능 최적화와 관련이 있습니다.

왜 Clustered Index에 접근하는가

  1. 잘못된 생각: Secondary Index에서 모든 것을 처리

    • WHERE 절과 ORDER BY 절은 Secondary Index에서 처리할 수 있는 부분입니다. 여기서 board_id에 맞는 데이터를 찾고, article_id로 정렬된 상태로 데이터를 순차적으로 찾아갑니다.
  2. 현실: Clustered Index로의 접근이 필요

    • SELECT *는 테이블의 모든 컬럼을 가져오는 쿼리로, 이 경우 데이터베이스는 필요 데이터가 Secondary Index에만 있지 않는다는 점에서 실제 데이터 레코드를 위해 Clustered Index에 접근해야 합니다.
    • 데이터베이스 시스템은 OFFSET을 처리하기 위해, 대량의 행을 건너뛰어야 하기 때문에 실제 데이터 위치에 대한 정보를 가져오기 위해 Clustered Index를 사용합니다.
    • 데이터베이스는 Secondary Index에서 기사 ID의 순서를 찾고, 그 기준에서 필요 레코드로 이동합니다. 하지만 최종적으로는 모든 데이터를 가져와야 하므로 Clustered Index에 접근해야 합니다.

성능 최적화 방안

  • 인덱스 커버링 사용: 만약 열 선택이 인덱스 커버링이 가능한 경우라면, Clustered Index 접근을 줄일 수 있습니다. 즉, 필요한 열만을 쿼리하여 인덱스만으로 데이터를 가져오도록 설정할 수 있습니다.
  • 전략 변경: OFFSET 값을 줄이도록 쿼리 구조를 변형하거나, 무한 스크롤 방식으로 변경하여 성능을 개선할 수 있습니다.

관련해서 다른 사용자가 질문한 유사한 질문이 있어 소개합니다. 이 게시물이 도움될 수 있습니다:

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

황은경님의 프로필 이미지
황은경

작성한 질문수

질문하기