ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MySql 조회 성능 최적화를 위한 Index 의 이해(2)
    Infra & Tools/MYSQL 2023. 9. 14. 23:04

    이전 글에서 인덱스의 특징 설명을 했으니,, 실습을 해봤다.

     

    -> 다음 문장이 실제인지 알아보자.

     

    1000 만건의 데이터의 통계를 위해 4000 만 건을 읽는 작업에서는(전체 테이블 레코드의 20 %) 인덱스를 이용하지 않는게 올바른 판단일 수가 있다.

     

     

     

    다음과 같이 인덱스를 명시하지 않았으면 인덱스가 있다면 옵티마이저가 알아서 인덱스를 설정한다.

    (그렇다고 항상 최적으로 인덱스 설정하는것도 아님)

     

    인덱스를 만들기 전에 ,  인덱스가 없는 경우를 먼저 측정을 하고, 인덱스를 생성한 후 비교를 해주자.

    select created_time ,updated_time ,count(feed_id) as count
    from feed
    where member_id = 4 and created_time between '2000-12-01' and '2022-02-06'
    GROUP BY member_id,created_time,updated_time;

     

     

    이제 3개의 인덱스를 만들고 비교를 해보자.

     

    create index feed__index_member_id
         on feed (member_id);
    
    create index feed__index_created_time
        on feed (created_time);
    
    create index feed__index_member_id_created_time
       on feed (member_id,created_time);

    데이터의 크기와 분포는 다음과 같다

    select count(*) from feed ;
    
    -- 210 * 10^4
    
    select member_id ,count(member_id)
    from feed
    group by member_id;

     

     

    member id 4 인경우

     

    인덱스가 없는 경우

    평균 1s 217ms  ->  type All

     

    멤버 인덱스인 경우

    ->   2s 217ms

    select created_time ,updated_time ,count(feed_id) as count
    from feed use index (feed__index_member_id)
    where member_id = 4 and created_time between '2000-12-01' and '2022-02-06'
    GROUP BY member_id,created_time,updated_time;

     

    -> 2s 207ms , 복합 인덱스

    select created_time ,updated_time ,count(feed_id) as count
    from feed use index (feed__index_member_id_created_time)
    where member_id = 4 and created_time between '2000-12-01' and '2022-02-06'
    GROUP BY member_id,created_time,updated_time;

    -> 3s 

    select created_time ,updated_time ,count(feed_id) as count
    from feed use index (feed__index_created_time)
    where member_id = 4 and created_time between '2000-12-01' and '2022-02-06'
    GROUP BY member_id,created_time,updated_time;

     

    member id 1 인경우  

     

    - 인덱스가 없는 경우

    평균 525  ms

    select created_time ,updated_time ,count(feed_id) as count
    from feed
    where member_id = 1 and created_time between '2000-12-01' and '2022-02-06'
    GROUP BY member_id,created_time,updated_time;

     

    - 인덱스가 있는 경우

    225~280  ms

    select created_time ,updated_time ,count(feed_id) as count
    from feed use index (feed__index_member_id_created_time)
    where member_id = 1 and created_time between '2000-12-01' and '2022-02-06'
    GROUP BY member_id,created_time,updated_time;

     

     

    데이터의 분포상에서 meberId 가 1 인경우 index 가 유리하고 ,  memberId 가 4 인경우는 그렇지 않다라는것을 확인했다.

     

     

    1000 만건의 데이터의 통계를 위해 4000 만 건을 읽는 작업에서는(전체 테이블 레코드의 20 %) 인덱스를 이용하지 않는게 올바른 판단일 수가 있다.

     

    = 선택도가 낮으면 인덱스를 고민한다.

     

     

    예를 들어

    성별 남성 여성인것의 인덱스를 건다면 탐색 범위는 1/2 이니 좋은 판단은 아닌 것 같다.

     

    결론    인덱스의  도입은 탐색 범위를 줄이자는 배경에서 나왔다라는걸 잊지 말자. 

Designed by Tistory.