인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

alopp님의 프로필 이미지
alopp

작성한 질문수

비전공자도 이해할 수 있는 MySQL 성능 최적화 입문/실전 (SQL 튜닝편)

이 다음에는 어떤 걸 공부해야 하나요?

질문이있습니다.

작성

·

151

·

수정됨

1

제가 선생님 강의를보고

테이블에 천만개의 데이터를 넣고 인덱스를 테스트하고있었는데요,

 

2가지 질문이 생겼습니다.

 

  1. 질문

    다음과 같이 익스플레인 에널라이즈를 하면 소요시간이 약 704ms 으로 나옵니다.

 

그런데 익스플레인 에널라이즈만 제거하고 다시 셀렉트를 하면 소요시간이 1.494로 증가하는데

 

단순 조회 쿼리와 익스플레인 에널라이즈 쿼리가 서로 다르게 동작해서 그런건가요?

 

분석때문에 에널라이즈쪽이 더 오래걸릴까 싶었는데 오히려 반대라서 왜 이런현상이 발생하는지 궁금합니다.

-> Filter: ((reservation.userId = 389788) or (reservation.seatId = 50))  (cost=11192 rows=10272) (actual time=2.33..678 rows=10271 loops=1)
    -> Deduplicate rows sorted by row ID  (cost=11192 rows=10272) (actual time=2.3..676 rows=10271 loops=1)
        -> Index range scan on reservation using idx_user over (userId = 389788)  (cost=1.11 rows=1) (actual time=0.115..0.115 rows=0 loops=1)
        -> Index range scan on reservation using idx_seat over (seatId = 50)  (cost=1038 rows=10271) (actual time=0.0497..2.77 rows=10271 loops=1)

 

  1. 질문


    제가 다음과 같은 쿼리에 인덱스를 걸며 테스트해보니


    복합인덱스 ( userId,seatId or reverse ) 는 전혀 인덱스를 활용하지않고 단일 인덱스를 각각 지정했을 경우에만 아래와같이 인덱스를 병합해서 사용하더라구요. 이렇게 속도를 절반으로 떨어뜨렸는데 아무래도 데이터가 천만개라 그런가 여전히 1초 이상의 시간이 소요되어서 선생님이 보셨을때 여기서 더 개선해볼 방법이 있는지 궁금합니다.

    where쪽을 건드려 보자니 둘중 하나라도 충족되면 가져와야하는 상황이라면 or 말고 다른건 떠오르질않았습니다.
    (에널라이즈는 시간이 1초 미만으로 나오지만 실제로 쿼리 돌려보면 소요시간 1.4초 이상으로 찍힙니다. )

CREATE INDEX idx_user ON reservation_entity(userId);
CREATE INDEX idx_seat ON reservation_entity(seatId);

SELECT
  `reservation`.`createdAt` AS `reservation_createdAt`,
  `reservation`.`updatedAt` AS `reservation_updatedAt`,
  `reservation`.`deletedAt` AS `reservation_deletedAt`,
  `reservation`.`id` AS `reservation_id`,
  `reservation`.`userId` AS `reservation_userId`,
  `reservation`.`concertId` AS `reservation_concertId`,
  `reservation`.`seatId` AS `reservation_seatId`,
  `reservation`.`status` AS `reservation_status`,
  `reservation`.`price` AS `reservation_price`,
  `reservation`.`concertName` AS `reservation_concertName`,
  `reservation`.`seatNumber` AS `reservation_seatNumber`,
  `reservation`.`openAt` AS `reservation_openAt`,
  `reservation`.`closeAt` AS `reservation_closeAt`
FROM 
  `reservation_entity` `reservation`
WHERE 
  `reservation`.`userId` = 389788 
  OR `reservation`.`seatId` = 50; 

-> Filter: ((reservation.userId = 389788) or (reservation.seatId = 50))  (cost=11192 rows=10272) (actual time=2.33..678 rows=10271 loops=1)
    -> Deduplicate rows sorted by row ID  (cost=11192 rows=10272) (actual time=2.3..676 rows=10271 loops=1)
        -> Index range scan on reservation using idx_user over (userId = 389788)  (cost=1.11 rows=1) (actual time=0.115..0.115 rows=0 loops=1)
        -> Index range scan on reservation using idx_seat over (seatId = 50)  (cost=1038 rows=10271) (actual time=0.0497..2.77 rows=10271 loops=1)

답변 1

0

JSCODE 박재성님의 프로필 이미지
JSCODE 박재성
지식공유자

안녕하세요 alopp님! 좋은 질문 해주셨네요👍😊
하나씩 답변 드려보겠습니다.

 


  1. 저도 이 부분은 왜 그런지 궁금해서 검색을 좀 해봤어요! 확실하진 않지만 추측하고 알게 된 정보를 알려드려 볼게요!

    일반적으로는 EXPLAIN ANALYZE가 분석을 같이하기 때문에 시간이 더 오래걸리는 경우가 많습니다. 하지만 EXPLAIN ANALYZE를 처리할 때 내부적으로 실제 Query를 실행시키지 않고 추정(샘플링)을 통해 조금 더 효율적으로 처리를 할 수도 있다고 합니다! 이런 이유로 인해 EXPLAIN ANALYZE로 처리했을 때 응답 시간이 더 작게 나올 수도 있습니다.

 


  1. 복합 인덱스를 활용하지 않은 이유는 WHERE문에서 AND가 아닌 OR 조건을 활용했기 때문입니다. 그리고 인덱스를 활용했음에도 불구하고 시간이 오래 걸리는 이유는 최종적으로 반환하는 데이터 개수가 많아서 오래 걸린다고 예상할 수 있습니다. 그리고 많은 데이터들을 가지고 Deduplicate 작업을 함으로써 시간이 오래 걸린 것으로 예상되네요!

    이 외로 궁금하신 점 있으시면 편하게 질문 또 남겨주세요~~~

alopp님의 프로필 이미지
alopp

작성한 질문수

질문하기