MySql 조회 성능 최적화를 위한 Index 의 이해(2)
이전 글에서 인덱스의 특징 설명을 했으니,, 실습을 해봤다.
-> 다음 문장이 실제인지 알아보자.
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 이니 좋은 판단은 아닌 것 같다.
결론 인덱스의 도입은 탐색 범위를 줄이자는 배경에서 나왔다라는걸 잊지 말자.