좋아요 순 노래 전체 조회 쿼리
select song.id, song.album_cover_url, song.created_at, song.length, song.singer, song.title, song.video_id, sum(coalesce(kp.like_count,0))
from song
left join killing_part kp on song.id=kp.song_id
group by song.id
Explain
song 만 개, 킬링파트 3만 개로 테스트했다.
type |
possible_keys |
key |
key_len |
ref |
rows |
filtered |
Extra |
ALL |
PRIMARY |
null |
null |
null |
9910 |
100 |
Using temporary |
ALL |
null |
null |
null |
null |
29478 |
100 |
Using where; Using join buffer (hash join) |
type 이 ALL 로 나오기 때문에, 전체 테이블 스캔이 발생했다.
개선 사항
id |
select_type |
table |
partitions |
type |
possible_keys |
key |
key_len |
ref |
rows |
filtered |
Extra |
1 |
SIMPLE |
song |
null |
index |
PRIMARY |
PRIMARY |
8 |
null |
9910 |
100 |
null |
1 |
SIMPLE |
kp |
null |
ref |
idx_kp_song_id |
idx_kp_song_id |
8 |
shook.song.id |
3 |
100 |
null |
살펴보는 row 의 수가 '크게' 줄었다!
특정 킬링파트 전체 댓글 쿼리
select comment.killing_part_id, comment.id, comment.content, comment.created_at, comment.member_id, m.id, m.created_at, m.email, m.nickname
from killing_part_comment comment
left join member m on m.id=comment.member_id
where comment.killing_part_id=?
Explain
member 가 1명이었음
comment 4만개 기준으로 테스트
table |
type |
possible_keys |
key |
key_len |
ref |
rows |
filtered |
Extra |
comment |
ALL |
null |
null |
null |
null |
40051 |
10 |
Using where |
m |
eq_ref |
PRIMARY |
PRIMARY |
8 |
shook.comment.member_id |
1 |
100 |
null |
마찬가지로 ALL 로 나오는 모습이다.
기존 성능 체크
COUNT_STAR |
SUM_TIMER_WAIT |
MIN_TIMER_WAIT |
AVG_TIMER_WAIT |
MAX_TIMER_WAIT |
SUM_LOCK_TIME |
2 |
41795000000 |
19135000000 |
20897500000 |
22660000000 |
15000000 |
### 개선사항 |
|
|
|
|
|
member_id
, killing_part_id
에 인덱스 걸기
table |
type |
possible_keys |
key |
key_len |
ref |
rows |
filtered |
Extra |
comment |
ref |
idx_killing_part_comment_killing_part_id |
idx_killing_part_comment_killing_part_id |
8 |
const |
18564 |
100 |
null |
m |
eq_ref |
PRIMARY |
PRIMARY |
8 |
shook.comment.member_id |
1 |
100 |
null |
확인하는 row 수가 2분의 1로 감소했다.
COUNT_STAR |
SUM_TIMER_WAIT |
MIN_TIMER_WAIT |
AVG_TIMER_WAIT |
MAX_TIMER_WAIT |
SUM_LOCK_TIME |
6 |
50175000000 |
797000000 |
8362500000 |
22660000000 |
30000000 |
성능도 최소 시간 기준 100분의 1로 크게 향상되었다.
스와이프하는 노래를 조회하는 쿼리 (비로그인)
select * from song s where s.id=?
select * from song s1_0
left join killing_part k1_0 on s1_0.id=k1_0.song_id
group by s1_0.id
having (
select sum(coalesce(k2_0.like_count,0))
from killing_part k2_0 where k2_0.song_id=?
)
or
(
sum(coalesce(k1_0.like_count,0))= (
select sum(coalesce(k3_0.like_count,0))
from killing_part k3_0
where k3_0.song_id=?
) and s1_0.id>?
)
)
order by sum(coalesce(k1_0.like_count,0)), s1_0.id
offset ? rows fetch first ? rows only
select *
from song s1_0
left join killing_part k1_0 on s1_0.id=k1_0.song_id
group by s1_0.id
having
sum(coalesce(k1_0.like_count,0))<
(
select sum(coalesce(k2_0.like_count,0))
from killing_part k2_0
where k2_0.song_id=?
)
or
( sum(coalesce(k1_0.like_count,0))=
(
select sum(coalesce(k3_0.like_count,0))
from killing_part k3_0
where k3_0.song_id=?
)
and s1_0.id<?
)
order by sum(coalesce(k1_0.like_count,0)) desc, s1_0.id desc
offset ? rows fetch first ? rows only
select * from killing_part k1_0 where k1_0.song_id=?
Explain
- 기준 노래보다 좋아요가 많은 데이터 조회 및 정렬
select_type |
table |
type |
possible_keys |
key |
ref |
rows |
Extra |
PRIMARY |
s1_0 |
ALL |
PRIMARY |
null |
null |
9910 |
Using temporary; Using filesort |
PRIMARY |
k1_0 |
ALL |
null |
null |
null |
29478 |
Using where; Using join buffer (hash join) |
SUBQUERY |
k3_0 |
ALL |
null |
null |
null |
29478 |
Using where |
SUBQUERY |
k2_0 |
ALL |
null |
null |
null |
29478 |
Using where |
모두 ALL Search 를 수행하고 있으며, filesort 또한 수행되고 있는 것을 볼 수 있다. (성능에 안 좋다는 건 다 들어간 인스턴스 쿼리;;)
- 기준 노래보다 좋아요가 적은 데이터 조회 및 정렬
select_type |
table |
type |
possible_keys |
key |
ref |
rows |
Extra |
PRIMARY |
s1_0 |
ALL |
PRIMARY |
null |
null |
9910 |
Using temporary; Using filesort |
PRIMARY |
k1_0 |
ALL |
null |
null |
null |
29478 |
Using where; Using join buffer (hash join) |
SUBQUERY |
k3_0 |
ALL |
null |
null |
null |
29478 |
Using where |
SUBQUERY |
k2_0 |
ALL |
null |
null |
null |
29478 |
Using where |
마찬가지로 ALL search 수행 중이다.
select_type |
table |
type |
key |
ref |
rows |
Extra |
SIMPLE |
k1_0 |
ALL |
null |
null |
29478 |
Using where |
ALL Search 진행 중이다.
성능 측정
COUNT_STAR |
SUM_TIMER_WAIT |
MIN_TIMER_WAIT |
AVG_TIMER_WAIT |
MAX_TIMER_WAIT |
SUM_LOCK_TIME |
4 |
432433000000 |
102933000000 |
108108250000 |
114617000000 |
119000000 |
COUNT_STAR |
SUM_TIMER_WAIT |
MIN_TIMER_WAIT |
AVG_TIMER_WAIT |
MAX_TIMER_WAIT |
SUM_LOCK_TIME |
5 |
510016000000 |
91359000000 |
102003200000 |
111161000000 |
31000000 |
COUNT_STAR |
SUM_TIMER_WAIT |
MIN_TIMER_WAIT |
AVG_TIMER_WAIT |
MAX_TIMER_WAIT |
SUM_LOCK_TIME |
4 |
99311000000 |
23335000000 |
24827750000 |
26468000000 |
14000000 |
개선 방법
killing_part
의 song_id
인덱싱
이후 성능 측정
COUNT_STAR |
SUM_TIMER_WAIT |
MIN_TIMER_WAIT |
AVG_TIMER_WAIT |
MAX_TIMER_WAIT |
SUM_LOCK_TIME |
20 |
1597450000000 |
65837000000 |
79872500000 |
114617000000 |
185000000 |
MIN_TIMER_WAIT 성능 30% 개선
COUNT_STAR |
SUM_TIMER_WAIT |
MIN_TIMER_WAIT |
AVG_TIMER_WAIT |
MAX_TIMER_WAIT |
SUM_LOCK_TIME |
20 |
1406030000000 |
53473000000 |
70301500000 |
111161000000 |
97000000 |
MIN_TIMER_WAIT 성능 250% 악화
COUNT_STAR |
SUM_TIMER_WAIT |
MIN_TIMER_WAIT |
AVG_TIMER_WAIT |
MAX_TIMER_WAIT |
SUM_LOCK_TIME |
10 |
101400000000 |
288000000 |
10140000000 |
26468000000 |
34000000 |