Inflearn brand logo image

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

모깅님의 프로필 이미지
모깅

작성한 질문수

6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법

3-7. 쿼리플랜 실제로 파악해보기.

인덱스 설계

해결된 질문

작성

·

28

·

수정됨

0

1. 현재 학습 진도

  • 몇 챕터/몇 강을 수강 중이신가요? 3-7

     

  • 여기까지 이해하신 내용은 무엇인가요?

 

2. 어려움을 겪는 부분

  • 어느 부분에서 막히셨나요?

    개인 프로젝트 중 여러 테이블이 where절 조건에 있을 때는 어떤식으로 인덱스를 설계해야 하나요??

  • 코드의 어떤 로직이 이해가 안 되시나요?

  • 어떤 개념이 헷갈리시나요?

 

3. 시도해보신 내용

  • 문제 해결을 위해 어떤 시도를 해보셨나요?

  • 에러가 발생했다면 어떤 에러인가요?

  • 현재 작성하신 코드를 공유해주세요

 select
        o1_0.order_id,
        o1_0.city,
        o1_0.street,
        o1_0.zipcode,
        o1_0.created_at,
        o1_0.deleted_at,
        o1_0.delivery_id,
        o1_0.member_id,
        o1_0.name,
        o1_0.no,
        o1_0.payment_id,
        o1_0.tid,
        o1_0.total_price,
        o1_0.updated_at 
    from
        orders o1_0 
    join
        member m1_0 
            on m1_0.member_id=o1_0.member_id 
    join
        delivery d1_0 
            on d1_0.id=o1_0.delivery_id 
    join
        payment p1_0 
            on p1_0.payment_id=o1_0.payment_id 
    where
        d1_0.delivery_status=? 
        and o1_0.created_at between ? and ? 
        and o1_0.total_price>=? 
    order by
        o1_0.total_price 
    limit
        ?, ?

orders테이블과 delivery 테이블 where절에서 조건이 걸려있습니다. 이럴 경우는 어떻게 해야 하나요??

쿼리 조건이 좀 이상할 수 있지만 공부하는 겸 여러 조건들을 시도하고 인덱스 설계하는 중입니다. ㅎㅎ

제가 시도해본 인덱스들은, orders 테이블에 create_at, total_price 복합 인덱스와 total_price, created_at 복합 인덱스이며 첫 번째 인덱스는 속도가 느려졌고 두번째 인덱스는 속도가 빨라졌습니다.

 

인덱스 X desc 결과

image.png

첫번째 인덱스 desc 결과

image.png

두번째 인덱스 desc 결과

image.png


 이후 delivery_status로 인덱스를 만들었더니 속도가 더 빨라졌습니다.

-> where 절에 여러개에 테이블이 조건으로 있더라도 각 테이블마다 인덱스를 생성해주면 될까요??

 

이렇게 구체적으로 알려주시면, 더 정확하고 도움이 되는 답변을 드릴 수 있습니다!

답변 2

0

딩코딩코님의 프로필 이미지
딩코딩코
지식공유자

모깅님 좋은 질문 해주셔서 감사합니다!!!

여러 테이블에서 WHERE절 조건이 있을 때의 인덱스 설계는 정말 실무에서 자주 마주치는 중요한 상황입니다. 실제로 경험하시면서 실험도 해보신 점 넘넘 훌륭합니다!!

 

여러 테이블에서 WHERE절 조건을 처리할 때는 두 가지 핵심을 고려해야 합니다. 첫째, MySQL은 Nested Loop Join을 기본으로 하기 때문에 각 테이블의 인덱스가 독립적으로 효과를 발휘하며, 둘째, 드라이빙 테이블을 먼저 최적화하는 것이 전체 성능에 가장 큰 영향을 줍니다!

실제로 EXPLAIN을 해보시면 orders 테이블을 먼저 읽고(드라이빙 테이블), 각 주문마다 member, delivery, payment 테이블에 조인하는 방식입니다.

따라서 성능 개선의 핵심은 orders 테이블의 조건절을 최대한 빠르게 처리하는 것이 중요합니다

즉, 여러 테이블의 WHERE절이 있을 때는 각 테이블별로 인덱스를 만들되, 드라이빙 테이블의 조건을 가장 우선으로 해야 합니다.

현재 orders 테이블에 created_at, total_price가 있으므로 아래와 같이 인덱스를 생성해봐도 좋을 것 같습니다

CREATE INDEX idx_orders_main ON orders (created_at, total_price);

CREATE INDEX idx_delivery_status ON delivery (delivery_status);

 

또한, 첫 번째 인덱스 (created_at, total_price)가 느렸던 이유는 ORDER BY total_price와 매칭되지 않았기 때문입니다. MySQL이 인덱스를 탔지만 추가 정렬이 필요했던 것으로 보입니다.

두 번째 인덱스 (total_price, created_at)가 빨라진 이유는 ORDER BY total_price를 인덱스로 바로 처리할 수 있었기 때문입니다.

delivery_status 인덱스 추가로 더 빨라진 건 정말 좋은 접근이에요. 각 테이블의 조건을 독립적으로 최적화할 수 있다는 걸 직접 확인하신 거라 좋습니다!

모깅님이 지금해보신 것처럼 실제 프로젝트에서 이런 최적화를 진행하면서 EXPLAIN 결과를 비교 분석한 경험을 쌓아보세요!! 넘넘 좋습니다

0

안녕하세요, 인프런 AI 인턴입니다. 모깅님.

여러 테이블이 관련된 쿼리에서 인덱스를 어떻게 설계해야 하는지에 대한 고민을 해주셨습니다. 쿼리 최적화를 위한 인덱스 설계는 데이터베이스 성능을 좌우하는 중요한 요소입니다. 질문의 SQL 쿼리에서는 orders 테이블과 delivery 테이블에 여러 조건이 걸려 있으며, 이를 고려한 인덱스 설계 전략을 설명드리겠습니다.

인덱스 설계 전략:

  1. 복합 인덱스 활용:

    • 여러 조건이 들어간 WHERE 절에서는 최소한 자주 사용되는 컬럼의 조합으로 복합 인덱스를 고려하세요.
    • 예를 들어, orders 테이블이라면 (delivery_status, created_at, total_price) 순서로 인덱스를 생성할 수 있습니다. 이때 delivery_status가 필터링을 통해 먼저 사용되는 조건이라면 선두에 위치시키는 것이 좋습니다.
  2. 인덱스 선택 순서:

    • 인덱스의 컬럼 순서는 중요합니다. 가장 먼저 필터링하고자 하는 조건을 가장 앞에 두는 것이 유리합니다. 데이터 분포와 사용 패턴에 따라 선택이 달라질 수 있습니다.
  3. 쿼리 실행 계획 분석:

    • EXPLAIN 명령어로 쿼리 실행 계획을 분석하여 어느 테이블 스캔이 병목인지 파악하세요.
    • 이를 통해 어떤 인덱스가 실질적으로 도움이 되는지 확인할 수 있습니다.
  4. 실험적인 접근:

    • 질문에서 언급하신 것처럼 여러 조합의 인덱스를 시도하여 성능 변화를 체감해보세요. 각 시도의 결과를 기록하여 가장 적합한 구조를 찾아나가는 과정이 중요합니다.
  5. 인덱스 유지 비용 고려:

    • 데이터 추가 및 수정 시 인덱스 유지에 드는 비용도 고려해야하며, 모든 경우에 걸맞는 인덱스는 아닐 수 있습니다. 인덱스는 빠른 조회를 위해 추가되지만, 데이터 변경이 잦다면 가중치를 다르게 볼 필요가 있습니다.

아래 링크는 유사한 상황에서 다른 사용자의 질문과 그에 대한 답변을 다룬 게시글입니다. 참고하시면 도움 될 것입니다:

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

모깅님의 프로필 이미지
모깅

작성한 질문수

질문하기