1. 개요
시스템을 운영하면서 요청건수가 쌓이게되어, 단순하게 조회하는 api 부터 시작해서, 요청의 통계등 관리자 사용 api가 점점 느려지는 것이 느껴졌다.
우선순위를 낮게 두어 계속 밀렸던 인덱싱을 적용하도록 결정했다.
✅ 인덱스란 무엇인가?
인덱스는 테이블의 특정 컬럼에 대해 검색 가능한 색인 구조를 만드는 것이다.
일반적으로 B-Tree 기반 인덱스가 기본이며, 정렬된 구조로 되어 있어 WHERE, JOIN, ORDER BY 등에서 전체 테이블 스캔을 막는다.
왜 인덱스가 성능을 올리는가?
- 전체 테이블을 순회하는 Full Table Scan 보다 빠르게 조회 가능
- 키를 통한 검색 범위 지정이 빨라짐
- 데이터가 많아질수록 효과가 더 커짐
다만, insert/update/delete는 오히려 느려질 수 있기때문에 신중하게 적용해야한다
작업하고 있는 시스템의 경우 사실상 delete는 없고 update 또한 드물다
읽기(조회) vs 쓰기(변경) 사이에서 더 무게를 두자면 읽기에 투자하기로 했다
2. Index를 만드는 조건
단순하게 생각해서 where 조건에 가장 많이 들어가는 column이 우선순위가 높다
(cardanality 가 높은 컬럼이 인덱스의 조건이 된다)
이번 시스템에 경우에서는 status이다
해당 요청의 진행상태가 어떤지 조회하는 api에서 빛을 발할것이다
예시)
#단일 인덱스
CREATE INDEX idx_request_status ON request(status);
#복합 인덱스
CREATE INDEX idx_type_status_created ON request(type, status, created_at);
검색 조건도 indexing에 유리하지만, join의 key 정렬 조건 등이 추가로 있을 것이다
3. 실제 적용 예시
앞서 정규화 한 글에서 보면 아래 3개의 테이블이 있다
사용자가 요청한 요청 정보를 보여주는 API에서는 위 테이블들을 join해서 보여줄 것이다
- request_content
- request_info
- request_approval
요청 정보 조회 쿼리 예시)
SELECT
ri.request_id,
rc.request_title,
ra.approver_id,
ra.approval_status,
ra.approved_at
FROM request_info ri
JOIN request_content rc
ON ri.request_id = rc.request_id
LEFT JOIN request_approval ra
ON ri.request_id = ra.request_id
WHERE ri.request_id = ?;
앞서 정리한대로 보면 join의 key가 되는 ri.request_id, rc.request_id , ra.request_id 가 인덱스가 필요할 것이다
Approval 테이블 인덱스 생성)
CREATE INDEX idx_approval_request_id ON request_approval (request_id);
FK로 설정한 것들에 대해 index를 설정한다
+ 결과 추가 필요
4. 고찰
index 적용 후에는 EXPLAIN으로 분석해야한다
'Back-end > SQL' 카테고리의 다른 글
| [레거시 정규화] DB 정규화 하기2 (0) | 2026.02.07 |
|---|---|
| [레거시 정규화] DB 정규화 하기1 (0) | 2026.02.07 |
| [SQL] GROUP BY 한 결과로 UPDATE 하는 법 (0) | 2021.07.27 |