crew (크루)
study_log (학습로그)
SELECT *
FROM crew
WHERE nickname >= "매트" AND nickname <= "토르"
ORDER BY nickname;
각 track(프론트, 백엔드)에서 nickname이 가장 빠른 사람들을 가져오는 쿼리 날린다고 가정
프론트에서 가장 빠른 꼬재
를 읽고 바로 백엔드 track으로 넘어가서 매트
만 읽으면 됨
CREATE INDEX idx_crew_track_nickname ON crew (track, nickname);
SELECT track, MIN(nickname) FROM crew GROUP BY track;
데이터를 하나하나 다 읽는 것
인덱스가 없는 경우 발생
인덱스가 있는 경우 발생
Field | Type | Null | Key | Default | Extra |
---|---|---|---|---|---|
id | int | No | Pri | null | auto_increment |
nickname | varchar(20) | NO | Null | ||
track | varchar(20) | No | Null | ||
age | int | No | Null |
서비스의 특성상 무엇에 대한 조회가 많이 일어나는지 파악
카디널리티가 높은 컬럼에 대해 인덱스 생성
그래서 발표자는 어디다가? nickname에 걸었음
ALTER TABLE crew ADD INDEX idx_crew_age_nickname (age, nickname);
age | nickname |
---|---|
... | ... |
23 | 티거 |
24 | 파랑 |
25 | 나인 |
25 | 무비 |
... | ... |
26 | 동키콩 |
28 | 리버 |
select * from crew where age >= 25;
SELECT * FROM crew Where age >= 26 AND nickname >= '토르';
토르
보다 뒤에 나오는 사람들을 가져 옴select * from crew where nickname >= '동키콩';
SELECT *
FROM crew
WHERE nickname BETWEEN 'a' AND 'd' AND track = 'BACKEND'
ALTER TABLE crew ADD INDEX idx_crew_nickname_track (nickname, track);
EXPLAIN SELECT *
FROM crew
WHERE nickname BETWEEN 'a' AND 'd' AND track = 'BACKEND';
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | crew | Null | All | idx_crew_nickname_track | NULL | NULL | NULL | 997853 | 3.78 | Using where |
SELECT *
FROM crew
WHERE nickname BETWEEN 'a' AND 'd' AND track = 'BACKEND'
SELECT nickname, track
FROM crew
WHERE nickname BETWEEN 'a' AND 'd' AND track = 'BACKEND'
EXPLAIN SELECT nickname, track
FROM crew
WHERE nickname BETWEEN 'a' AND 'd' AND track = 'BACKEND';
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | crew | Null | range | idx_crew_nickname_track | NULL | NULL | NULL | 997853 | 3.78 | Using where; Using index |
SELECT id, nickname, track
FROM crew
WHERE nickname BETWEEN 'a' AND 'd' AND track = 'BACKEND';
EXPLAIN SELECT id, nickname, track
FROM crew
WHERE nickname BETWEEN 'a' AND 'd' AND track = 'BACKEND';
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | crew | Null | range | idx_crew_nickname_track | NULL | NULL | NULL | 997853 | 3.78 | Using where; Using index |
nickname | track | primary key(id) |
---|---|---|
리버 | BACKEND | 79 |
매트 | BACKEND | 26 |
토르 | BACKEND | 27 |
... | ... | ... |
study_log (학습로그)
1명의 크루는 N개의 학습 로그 작성 가능
type에는 SHARE, QUESTION 등 학습 로그의 목적을 명시
type 기준 빠른 조회를 위한 인덱스 생성
ALTER TABLE study_log ADD INDEX idx_study_log_type (type);
SELECT *
FROM study_log
WHERE type = 'QUESTION'
AND created_at BETWEEN '2022-10-07 00:00' AND '2022-10-13 00:00';
Explain SELECT *
FROM study_log
WHERE type = 'QUESTION'
AND created_at BETWEEN '2022-10-07 00:00' AND '2022-10-13 00:00';
id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | study_log | ref | idx_study_log_type | idx_study_log_type | 82 | const | 487403 | 11.11 | Using where |
idx_study_log_type을 통한 REF
Extra 컬럼의 Using where
ALTER TABLE study_log ADD INDEX idx_study_log_type_careated_at (type, created_at);
Explain SELECT *
FROM study_log
WHERE type = 'QUESTION'
AND created_at BETWEEN '2022-10-07 00:00' AND '2022-10-13 00:00';
id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | study_log | range | idx_study_log_type_created_at | idx_study_log_type_created_at | 82 | const | 487403 | 11.11 | Using index condition |
Extra 컬럼의 Using Index Condition은 인덱스 컨디션 푸시다운 으로 인해 표시
인덱스 컨디션 푸시다운(ICP, Index Condition Pushdown)이란, MySQL이 인덱스를 사용하여 테이블에서 행을 검색하는 경우의 최적화를 의미
ICP를 활성화하고 인덱스의 컬럼만 사용하여 WHERE 조건의 일부를 평가할 수 있는 경우 MySQL 엔진은 WHERE 조건 부분을 스토리지 엔진으로 푸시
ICP는 최신 버전의 MySQL을 사용할 경우 기본적으로 활성화