Infra & Tools/MYSQL

MySql 조회 성능 최적화를 위한 Index 의 이해(2)

sung.hyun.1204 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 이니 좋은 판단은 아닌 것 같다.

 

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