대용량 데이터셋(100만 건)에서 인덱스 유무에 따른 성능 차이를 비교하여,
인덱스가 실제 쿼리 성능에 미치는 영향을 측정한다.
| 항목 | 내용 |
|---|---|
| DBMS | MySQL 8.x (InnoDB) |
| 테이블 | tasks_noidx, tasks_idx |
| 데이터 건수 | 각 테이블당 1,000,000건 |
| 비교 조건 | status = 'DONE' AND is_deleted = false |
| 쿼리 캐시 제거 | SQL_NO_CACHE 사용 |
| 측정 도구 | macOS 터미널 + time 명령어 |
CREATE TABLE tasks_noidx (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
...
status VARCHAR(20),
is_deleted BOOLEAN NOT NULL,
...
);
-- tasks_idx는 아래 인덱스만 추가됨
CREATE INDEX idx_status_deadline_deleted ON tasks_idx(status, deadline, is_deleted);
SELECT SQL_NO_CACHE COUNT(*)
FROM tasks_xxx
WHERE status = 'DONE' AND is_deleted = false;
xxx는 tasks_noidx 또는 tasks_idx| 회차 | 실행 시간 (sec) |
|---|---|
| 1 | 2.699 |
| 2 | 1.549 |
| 3 | 1.368 |
| 4 | 1.247 |
| 5 | 1.275 |
| 6 | 1.192 |
| 7 | 1.199 |
| 8 | 1.233 |
| 9 | 1.151 |
| 10 | 1.158 |
| 회차 | 실행 시간 (sec) |
|---|---|
| 1 | 2.704 |
| 2 | 1.150 |
| 3 | 1.124 |
| 4 | 1.773 |
| 5 | 1.131 |
| 6 | 1.121 |
| 7 | 1.122 |
| 8 | 1.777 |
| 9 | 1.399 |
| 10 | 1.309 |
| 항목 | tasks_noidx | tasks_idx |
|---|---|---|
| 평균 | 1.461초 | 1.407초 |
| 중앙값 | 1.240초 | 1.233초 |
| 최대값 | 2.704초 | 2.699초 |
COUNT(*) + WHERE 단순 조건에서는 인덱스 효과가 제한적ORDER BY deadline DESC LIMIT 100 조건 추가 실험JOIN, UPDATE, DELETE 성능 비교for i in {1..10}; do
time mysql -u root -p -D taskflow -e "SELECT SQL_NO_CACHE COUNT(*) FROM tasks_idx WHERE status = 'DONE' AND is_deleted = false;";
done
InnoDB 스토리지 엔진이 디스크 I/O를 줄이기 위해 사용하는 메모리 공간
즉,
디스크 I/O는 매우 느림.
InnoDB Buffer Pool에는 주로 다음이 올라옴:
| 종류 | 설명 |
|---|---|
| 데이터 페이지 | 테이블의 실제 행 데이터 |
| 인덱스 페이지 | B+Tree 인덱스 노드 |
| Undo Log | 트랜잭션 롤백을 위한 변경 이력 |
| Insert Buffer | 보조 인덱스에 대한 변경사항 |
| Adaptive Hash Index | 자주 사용되는 인덱스의 해시 |
SQL_NO_CACHE는 쿼리 결과를 **쿼리 캐시(Query Cache)**에 저장하지 말라는 옵션 (MySQL 8.0에서는 제거됨)
그러나 Buffer Pool은 여전히 동작
즉, SQL_NO_CACHE를 써도 InnoDB가 데이터 페이지 자체를 메모리에 유지하기 때문에,
똑같은 쿼리를 반복해도 성능이 일정하게 나오는 것처럼 보일 수 있음
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
[mysqld]
innodb_buffer_pool_size = 1G
| 항목 | 설명 |
|---|---|
| 역할 | 디스크 I/O 줄이고 성능 향상 |
| 저장하는 것 | 데이터·인덱스 페이지 등 |
| 위치 | 메인 메모리(RAM) |
| 사용 조건 | 자동 사용됨 (쿼리와 무관) |
| SQL_NO_CACHE 영향 | 없음 (별도 메커니즘) |
Buffer Pool은 DB 쿼리 결과가 아니라, "데이터 자체"를 메모리에 유지
SQL_NO_CACHE는 Query Cache를 무시할 뿐, InnoDB Buffer Pool은 계속 작동
쿼리 성능 실험에서 Buffer Pool이 영향을 줄 수 있으므로, 완전한 비교를 위해선 innodb_buffer_pool_size=0으로 설정하거나 서버 재시작이 필요 (현실적이지는 않음)