inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

게시글 목록 API - 무한 스크롤 설계

'soft Delete 시 index 설정' 답변한 내용에서 질문 있습니다.

해결된 질문

129

soap

작성한 질문수 37

0

https://www.inflearn.com/community/questions/1516484

해당 게시글의 답변중 아래 문장이 이해가 잘 안갑니다 ㅠ

 

물론, 삭제된 데이터가 극히 적다면, 위 비용은 딱히 문제가 안될 수도 있긴 합니다.

삭제되지 않은 데이터가 훨씬 많다면, 조건에 일치(isDeleted=false)하는 데이터를 빠르게 찾을 수 있으므로, 스캔하는 범위는 어차피 적을테니깐요.


하지만 삭제된 데이터가 많아질수록 조건에 일치하는 데이터를 찾기 위해 스캔하는 범위가 길어질 수 있으므로, 인덱스를 걸어둬야 빠르게 조회가 가능합니다!

인덱스를 걸지 않았을때 삭제되지 않은 데이터(isDeleted = false)가 훨씬 많다면 스캔하는 범위가 적은 이유를 잘 모르겠습니다..

인덱스가 없으면 삭제된 데이터가 많든, 많지 않든 무조껀 풀 스캔을 해서 스캔 범위는 똑같은게 아닌걸까요?

또한, 데이터 연속성도 스캔할시 관련이 있는건지 궁금합니다.

imagess

인덱스가 없을때 where isDeleted = false 쿼리 실행시 id가 4번까지만 스캔해서 스캔 범위가 적은걸까요?

image

직전 조건와 같을때 위와 같이 데이터가 흐트러져있다면 풀스캔을 하는 걸까요?

 

인덱스 공부좀 해야겠네요 흙흙

 

 

java mysql spring-boot kafka redis

답변 1

1

쿠케

dncjf64님, 안녕하세요!

 

인덱스를 걸지 않았을때 삭제되지 않은 데이터(isDeleted = false)가 훨씬 많다면 스캔하는 범위가 적은 이유를 잘 모르겠습니다..

 

극단적인 상황으로,

  • 삭제되지 않은 데이터(isDeleted = false) 데이터 1억개

  • 삭제된 데이터(isDeleted = true) 데이터 10개

위처럼 데이터가 있다고 가정해보겠습니다.

삭제된 데이터가 극히 적은 상황입니다.

그리고, 조회해야하는 데이터는 삭제되지 않은 데이터(isDeleted=false)입니다.

즉, 스캔하는 과정 중 isDeleted=true는 skip해야 됩니다.

그런데 삭제된 데이터(isDeleted=true)인 데이터는 10개 밖에 안되기 때문에,

isDeleted=true를 skip 해봤자 최대 10개만 스킵하면 됩니다.

페이징을 수행하면 limit으로 제한된 개수만 찾으면 되므로,

꼭 전체 데이터를 스캔할 필요 없이 isDeleted=false인 데이터는 빠르게 찾을 수 있습니다.

페이지당 30개의 데이터를 불러오고, 첫 페이지에서 isDeleted=true인 데이터가 한 개도 없었다면,

그냥 30개 스캔해서 바로 가져오면 됩니다.

스캔 범위에 isDeleted=true가 10개 포함되어 있었더라도, 그냥 10번만 skip하면 됩니다.

 

인덱스가 없을때 where isDeleted = false 쿼리 실행시 id가 4번까지만 스캔해서 스캔 범위가 적은걸까요?

맞습니다! 전체 데이터를 스캔 하기 전에, 어차피 조건을 충족하는 limit만큼 가져오면 되므로, 데이터를 금방 찾을 수 있습니다.

 

직전 조건와 같을때 위와 같이 데이터가 흐트러져있다면 풀스캔을 하는 걸까요?

조건에 맞는 데이터 limit 을 채웠다면, 그냥 바로 응답하면 됩니다.

삭제된 데이터가 극히 적다면, 어차피 스킵해야 할 데이터는 적어지므로 limit은 금방 채우게 됩니다.

 

정 반대의 상황으로,

  • 삭제되지 않은 데이터(isDeleted = false) 데이터 10개

  • 삭제된 데이터(isDeleted = true) 데이터 1억개

위처럼 데이터가 있다고 가정해보겠습니다.

삭제되지 않은 데이터는 전체 1억10개의 데이터 중에서 10개 밖에 되지 않습니다.

즉, 삭제되지 않은 데이터를 조회하려면, 삭제된 데이터를 스킵하는 과정에서 최대 1억개의 데이터를 모두 스캔하며 스킵해야할 수 있습니다.

 

약간 다른 이야기인데,

isDeleted가 인덱스에 포함되어 있지 않으면 다음과 같은 문제도 있습니다.

아무튼 다른 인덱스로 인해 테이블 풀스캔이 아니라 세컨더리 인덱스 스캔을 해야하는 상황이라고 가정해보겠습니다.

세컨더리 인덱스에 isDeleted 데이터가 포함되어 있지 않기 때문에, 조건을 판별하려면 항상 클러스터드 인덱스에 접근해서 isDeleted 값을 확인해야 합니다.

이렇게 되면 커버링 인덱스 최적화 기법은 사용 못하게 됩니다.

 

근데 대부분은 쿼리 패턴에 따라 인덱스를 만드는 경우가 훨씬 많긴 합니다.

어차피 데이터 분포까지 고려해야 할 극단적인 상황은 잘 나오지 않을 수 있고,

그런 상황까지 정말 다 고려가 필요하다면 그때 고민해서 개선해볼 수 있습니다.

데이터 분포, 인덱스 등 상황에 따라 내용이 달라지는 것들은, 인덱스 구조와 동작 원리 기반으로 잘 생각해보면 어떤 식으로 동작할지 유추해볼 수 있습니다.

쿼리 플랜을 직접적으로 확인할 수도 있고요.

이건 계속 깊이 고민하고 경험하는 과정이 있다보면 점점 빠르게 정리되고 익숙해질 것 같네요!

 

혹시 더 궁금한 점 있으시면 편히 문의 주세요!

@Version 어노테이션이 붙은 필드는 낙관적 락이든 비관적 락이든 업데이트가 됩니다.

0

31

1

consumer에서 에러가 발생할 경우 데이터 유실 문의

0

49

2

게시글 테스트 데이터 삽입

0

51

2

정렬, 필터, 검색 등의 조건이 붙을 경우 최적화할 수 있는 방법이 무엇이 있을까요?

0

104

2

좋아요 기능 정합성 보장 방법

0

98

2

좋아요 동시성처리 최적의 선택?

1

138

2

프론트엔드 msa 환경 api 주소 통합? 과 서버끼리 통신 방식에대해

0

92

2

안녕하세요 무한스크롤 강의듣다가 질문이 있습니다.

0

61

1

조회수 조회 로직 질문

1

67

2

비로그인 유저도 어뷰징 방지 정책

1

73

2

CommentServiceTest의 테스트 로직 질문

0

54

2

무한 스크롤 방식에서 페이지 번호 방식 쿼리의 문제점 의문

1

74

2

path 쿼리 관련 질문드립니다!

0

60

2

antigravity 에디터를 쓰신다면 종료해주세요

1

123

0

프로젝트 구조

0

88

2

article_like_count api test

0

79

2

이벤트 페이로드 객체의 생성 방식이 팩토리 메서드 패턴이 아닌 빌더 패턴인 이유가 궁금합니다!.

0

104

2

[33. 좋아요 수 구현] 에서 테스트 하는 화면 동시성 문제

0

92

2

findByPath에서 articleId로도 검색을 해야 할 것 같아요.

0

94

3

jpa ddl-auto none을 하는 이유와 join 방법

0

97

2

팩터리 메소드와 response 객체 사용 이유가 궁금합니다!

0

91

2

커서 기반 페이지네이션 과 무한 스크롤링

0

111

2

게시글 생성 로직에서 오류 발생시 redis 게시글 수 되돌리기

0

97

2

멀티 모듈이 아닌 MSA 환경에서 common

0

158

2