해결된 질문
작성
·
85
0
https://www.inflearn.com/community/questions/1516484
해당 게시글의 답변중 아래 문장이 이해가 잘 안갑니다 ㅠ
물론, 삭제된 데이터가 극히 적다면, 위 비용은 딱히 문제가 안될 수도 있긴 합니다.
삭제되지 않은 데이터가 훨씬 많다면, 조건에 일치(isDeleted=false)하는 데이터를 빠르게 찾을 수 있으므로, 스캔하는 범위는 어차피 적을테니깐요.
하지만 삭제된 데이터가 많아질수록 조건에 일치하는 데이터를 찾기 위해 스캔하는 범위가 길어질 수 있으므로, 인덱스를 걸어둬야 빠르게 조회가 가능합니다!
인덱스를 걸지 않았을때 삭제되지 않은 데이터(isDeleted = false)가 훨씬 많다면 스캔하는 범위가 적은 이유를 잘 모르겠습니다..
인덱스가 없으면 삭제된 데이터가 많든, 많지 않든 무조껀 풀 스캔을 해서 스캔 범위는 똑같은게 아닌걸까요?
또한, 데이터 연속성도 스캔할시 관련이 있는건지 궁금합니다.
인덱스가 없을때 where isDeleted = false 쿼리 실행시 id가 4번까지만 스캔해서 스캔 범위가 적은걸까요?
ㄸ
직전 조건와 같을때 위와 같이 데이터가 흐트러져있다면 풀스캔을 하는 걸까요?
인덱스 공부좀 해야겠네요 흙흙
답변 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 값을 확인해야 합니다.
이렇게 되면 커버링 인덱스 최적화 기법은 사용 못하게 됩니다.
근데 대부분은 쿼리 패턴에 따라 인덱스를 만드는 경우가 훨씬 많긴 합니다.
어차피 데이터 분포까지 고려해야 할 극단적인 상황은 잘 나오지 않을 수 있고,
그런 상황까지 정말 다 고려가 필요하다면 그때 고민해서 개선해볼 수 있습니다.
데이터 분포, 인덱스 등 상황에 따라 내용이 달라지는 것들은, 인덱스 구조와 동작 원리 기반으로 잘 생각해보면 어떤 식으로 동작할지 유추해볼 수 있습니다.
쿼리 플랜을 직접적으로 확인할 수도 있고요.
이건 계속 깊이 고민하고 경험하는 과정이 있다보면 점점 빠르게 정리되고 익숙해질 것 같네요!
혹시 더 궁금한 점 있으시면 편히 문의 주세요!