Stage 서버에서 DB index 적용 계획 문서 작성

This commit is contained in:
2026-09-15 11:05:39 +09:00
parent 3da9bfc458
commit 15d3537928
7 changed files with 265 additions and 42 deletions
@@ -9,12 +9,14 @@
## 단계별 진행 ## 단계별 진행
| # | 작업 | 문서 | | # | 작업 | 문서 | 소요시간 |
|---|---|---| |---|---|---|---|
| **1** | 인덱스 추가 전 성능 측정 (EXPLAIN, 실행 시간) | `01-baseline.md` | | **01** | 사전 측정: 테이블 크기, 월별 적재량, 중복 확인 | `01-premeasure.md` | 20분 |
| **2** | 인덱스 추가 SQL 실행 | `02-add-indexes.md` | | **02** | 인덱스 추가 전 성능 측정 (EXPLAIN, 실행 시간) | `02-baseline.md` | 15분 |
| **3** | 인덱스 추가 후 성능 측정 및 비교 | `03-verify.md` | | **03** | 인덱스 추가 SQL 실행 | `03-add-indexes.md` | 5분 |
| **4** | 체크리스트 | `04-checklist.md` | | **04** | 인덱스 추가 후 성능 측정 및 비교 | `04-verify.md` | 15분 |
| **05** | 체크리스트 | `05-checklist.md` | 10분 |
| | **총 소요시간** | | **약 1시간 15분** |
--- ---
@@ -0,0 +1,208 @@
# 01단계: 사전 측정 절차 (사전준비)
> 개선 전 현재 상태를 정확히 파악합니다. (개선 전/후 비교의 기준점)
>
> 참고: `doc/plan/db/01-improvement-overview.md`의 **7장 사전 측정 절차**와 동일
---
## 0-1. 테이블·인덱스 크기
```bash
mariadb -h mariadb.jisangs.com -u root -p chocomae -e "
SELECT TABLE_NAME,
TABLE_ROWS AS approx_rows,
ROUND(DATA_LENGTH / 1024 / 1024, 1) AS data_mb,
ROUND(INDEX_LENGTH / 1024 / 1024, 1) AS index_mb
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'chocomae'
ORDER BY DATA_LENGTH DESC;" > premeasure_table_sizes.txt
cat premeasure_table_sizes.txt
```
**저장할 수치:**
- `best_record` data_mb, index_mb
- `typing_exam_record` data_mb, index_mb
---
## 0-2. 월별 적재량 (증가 속도)
```bash
mariadb -h mariadb.jisangs.com -u root -p chocomae -e "
SELECT DATE_FORMAT(RecordDateTime, '%Y-%m') AS ym, COUNT(*) AS cnt
FROM best_record
GROUP BY ym
ORDER BY ym;" > premeasure_monthly_load.txt
cat premeasure_monthly_load.txt
```
**확인할 점:**
- 최근 3개월 증가 추이
- 월 평균 증가량
---
## 0-3. 대표 쿼리 기준값 (EXPLAIN)
### 3-1. 기록이 많은 선생님·앱 찾기
```bash
mariadb -h mariadb.jisangs.com -u root -p chocomae -e "
SELECT MaestroID, AppID, COUNT(*) AS cnt
FROM best_record
WHERE RecordDateTime >= NOW() - INTERVAL 30 DAY
GROUP BY MaestroID, AppID
ORDER BY cnt DESC
LIMIT 5;" > premeasure_top_maestro_app.txt
cat premeasure_top_maestro_app.txt
```
**결과 예:**
```
| MaestroID | AppID | cnt |
|-----------|-------|-----|
| 123 | 5 | 450 |
| 456 | 2 | 320 |
...
```
→ 다음 단계에서 사용할 값 메모 (예: MaestroID=123, AppID=5)
---
### 3-2. 일간 랭킹 쿼리 EXPLAIN
위에서 나온 MaestroID, AppID를 사용 (예: 123, 5):
```bash
mariadb -h mariadb.jisangs.com -u root -p chocomae -e "
EXPLAIN FORMAT=JSON
SELECT BR.PlayerID, U.Name, MAX(BR.BestRecord) AS HighScore
FROM best_record BR, player U
WHERE BR.MaestroID = 123
AND BR.PlayerID = U.PlayerID
AND YEAR(BR.RecordDateTime) = YEAR('2026-09-14')
AND MONTH(BR.RecordDateTime) = MONTH('2026-09-14')
AND DAYOFMONTH(BR.RecordDateTime) = DAYOFMONTH('2026-09-14')
AND BR.AppID = 5
GROUP BY BR.PlayerID
ORDER BY MAX(BR.BestRecord) DESC;" > premeasure_explain_daily_ranking.json
cat premeasure_explain_daily_ranking.json
```
**확인할 점:**
```json
{
"query_block": {
"select_list": [...],
"table": {
"table_name": "best_record",
"type": "ALL", ( )
"key": null,
"rows": 1206768
}
}
}
```
---
## 0-4. 슬로우 쿼리 로그 활성화 (선택)
```bash
mariadb -h mariadb.jisangs.com -u root -p chocomae -e "
SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 1;
SET GLOBAL log_output = 'TABLE';"
```
**메모:** 스테이징이므로 언제든 켜도 됨 (운영은 신중하게)
---
## 0-5. 최고기록 테이블 중복 점검
```bash
mariadb -h mariadb.jisangs.com -u root -p chocomae -e "
-- app_highest_record 중복 확인
SELECT MaestroID, PlayerID, AppID, COUNT(*) AS cnt
FROM app_highest_record
GROUP BY MaestroID, PlayerID, AppID
HAVING cnt > 1
ORDER BY cnt DESC
LIMIT 10;" > premeasure_app_highest_duplicates.txt
mariadb -h mariadb.jisangs.com -u root -p chocomae -e "
-- typing_exam_highest_record 중복 확인
SELECT MaestroID, PlayerID, WritingID, COUNT(*) AS cnt
FROM typing_exam_highest_record
GROUP BY MaestroID, PlayerID, WritingID
HAVING cnt > 1
ORDER BY cnt DESC
LIMIT 10;" > premeasure_exam_highest_duplicates.txt
echo "=== app_highest_record 중복 ===" && cat premeasure_app_highest_duplicates.txt
echo "=== typing_exam_highest_record 중복 ===" && cat premeasure_exam_highest_duplicates.txt
```
**중복이 있으면:**
- 안1에서 UNIQUE 키 추가 전에 정리 필요
---
## 0-6. 측정 결과 기록 양식
아래 표를 파일로 저장:
```bash
cat > premeasure_summary.txt << 'EOF'
=== 사전 측정 결과 (2026-09-15) ===
1. 테이블 크기
- best_record data_mb: ____
- best_record index_mb: ____
- typing_exam_record data_mb: ____
- typing_exam_record index_mb: ____
2. 월별 적재량
- 최근 1개월: ____ 행
- 최근 3개월 평균: ____ 행/월
3. 테스트용 선생님·앱
- MaestroID: ____
- AppID: ____
- 30일 기록 수: ____
4. 일간 랭킹 EXPLAIN
- type: ____ (현재: ALL 예상)
- key: ____ (현재: null 예상)
- rows: ____ (현재: 1206768 근처 예상)
5. 최고기록 테이블 중복
- app_highest_record 중복: ____ 건
- typing_exam_highest_record 중복: ____ 건
6. 준비 확인
☐ 테이블 크기 확인
☐ EXPLAIN 결과 저장
☐ 중복 확인
☐ Slow query log 켜기 (선택)
다음: 02-baseline.md로 이동
EOF
cat premeasure_summary.txt
```
---
## 다음 단계
✅ 사전 측정 완료 → **02-baseline.md로 이동**
(사전 측정 수치가 모두 위의 txt/json 파일에 저장되었습니다)
@@ -1,10 +1,12 @@
# 1단계: 개선 전 성능 측정 (베이스라인) # 02단계: 개선 전 성능 측정 (베이스라인)
> 인덱스 추가 전 EXPLAIN과 실행 시간을 측정해 개선 효과의 기준점을 만듭니다. > 인덱스 추가 전 EXPLAIN과 실행 시간을 측정해 개선 효과의 기준점을 만듭니다.
>
> ⚠️ **사전 필수**: 먼저 `01-premeasure.md`를 완료하세요 (테이블 크기, 중복 확인 등)
--- ---
## 1-1. Slow Query Log 활성화 ## 2-1. Slow Query Log 활성화
```sql ```sql
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL slow_query_log = 'ON';
@@ -16,7 +18,7 @@ SHOW VARIABLES LIKE 'slow_query%';
--- ---
## 1-2. 핵심 쿼리 EXPLAIN 분석 ## 2-2. 핵심 쿼리 EXPLAIN 분석
### 쿼리 1: 시간별 기록 조회 (느린 예상) ### 쿼리 1: 시간별 기록 조회 (느린 예상)
@@ -33,8 +35,8 @@ LIMIT 10\G
mariadb -h mariadb.jisangs.com -u root -p chocomae -e " mariadb -h mariadb.jisangs.com -u root -p chocomae -e "
EXPLAIN FORMAT=JSON SELECT * FROM best_record EXPLAIN FORMAT=JSON SELECT * FROM best_record
WHERE MaestroID = 1 WHERE MaestroID = 1
AND DATE(RecordDateTime) = DATE(NOW()) AND RecordDateTime >= DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00')
AND HOUR(RecordDateTime) = HOUR(NOW()) AND RecordDateTime < DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00') + INTERVAL 1 HOUR
LIMIT 10;" > baseline_query1_explain.json LIMIT 10;" > baseline_query1_explain.json
cat baseline_query1_explain.json cat baseline_query1_explain.json
@@ -79,7 +81,7 @@ cat baseline_query2_explain.json
--- ---
## 1-3. 실행 시간 측정 ## 2-3. 실행 시간 측정
```bash ```bash
cat > baseline_test.sql << 'EOF' cat > baseline_test.sql << 'EOF'
@@ -116,7 +118,7 @@ tail baseline_results.txt # real, user, sys 시간 확인
--- ---
## 1-4. 결과 기록 ## 2-4. 결과 기록
**파일로 저장된 결과:** **파일로 저장된 결과:**
``` ```
@@ -139,4 +141,4 @@ baseline_results.txt ← 실행 시간
## 다음 단계 ## 다음 단계
✅ 베이스라인 측정 완료 → **02-add-indexes.md로 이동** ✅ 베이스라인 측정 완료 → **03-add-indexes.md로 이동**
@@ -4,7 +4,7 @@
--- ---
## 2-1. 인덱스 추가 SQL 준비 ## 3-1. 인덱스 추가 SQL 준비
```bash ```bash
cat > add_indexes.sql << 'EOF' cat > add_indexes.sql << 'EOF'
@@ -48,7 +48,7 @@ cat add_indexes.sql # 확인
--- ---
## 2-2. 인덱스 추가 실행 ## 3-2. 인덱스 추가 실행
### 스테이징이므로 언제든 가능 ### 스테이징이므로 언제든 가능
@@ -76,7 +76,7 @@ watch -n 10 'mariadb -h mariadb.jisangs.com -u root -p -e "SHOW PROCESSLIST\G" |
--- ---
## 2-3. 인덱스 생성 확인 ## 3-3. 인덱스 생성 확인
```bash ```bash
mariadb -h mariadb.jisangs.com -u root -p chocomae -e "SHOW INDEXES FROM best_record;" | grep idx_ mariadb -h mariadb.jisangs.com -u root -p chocomae -e "SHOW INDEXES FROM best_record;" | grep idx_
@@ -95,4 +95,4 @@ mariadb -h mariadb.jisangs.com -u root -p chocomae -e "SHOW INDEXES FROM best_re
## 다음 단계 ## 다음 단계
✅ 인덱스 추가 완료 → **03-verify.md로 이동** ✅ 인덱스 추가 완료 → **04-verify.md로 이동**
@@ -4,7 +4,7 @@
--- ---
## 3-1. EXPLAIN 재분석 ## 4-1. EXPLAIN 재분석
### 쿼리 1: 원래 쿼리 (함수 사용 - 아직 느림) ### 쿼리 1: 원래 쿼리 (함수 사용 - 아직 느림)
@@ -43,7 +43,7 @@ cat after_query2_improved_explain.json
--- ---
## 3-2. 실행 시간 재측정 ## 4-2. 실행 시간 재측정
```bash ```bash
cat > verify_test.sql << 'EOF' cat > verify_test.sql << 'EOF'
@@ -80,7 +80,7 @@ cat verify_results.txt
--- ---
## 3-3. 성능 비교표 ## 4-3. 성능 비교표
```bash ```bash
cat > comparison.txt << 'EOF' cat > comparison.txt << 'EOF'
@@ -112,7 +112,7 @@ cat comparison.txt
--- ---
## 3-4. Slow Query Log 확인 ## 4-4. Slow Query Log 확인
```bash ```bash
# Synology의 slow query log 확인 # Synology의 slow query log 확인
@@ -133,4 +133,4 @@ SELECT ... (개선된 쿼리)
## 다음 단계 ## 다음 단계
✅ 개선 효과 검증 완료 → **04-checklist.md로 이동** ✅ 개선 효과 검증 완료 → **05-checklist.md로 이동**
@@ -16,7 +16,7 @@
--- ---
## 베이스라인 측정 (01-baseline.md) ## 베이스라인 측정 (02-baseline.md)
- [ ] 핵심 쿼리 EXPLAIN 분석 저장 - [ ] 핵심 쿼리 EXPLAIN 분석 저장
- baseline_query1_explain.json - baseline_query1_explain.json
@@ -27,7 +27,7 @@
--- ---
## 인덱스 추가 (02-add-indexes.md) ## 인덱스 추가 (03-add-indexes.md)
- [ ] add_indexes.sql 준비 - [ ] add_indexes.sql 준비
- [ ] 인덱스 추가 SQL 실행 - [ ] 인덱스 추가 SQL 실행
@@ -37,7 +37,7 @@
--- ---
## 개선 효과 검증 (03-verify.md) ## 개선 효과 검증 (04-verify.md)
- [ ] EXPLAIN 재분석 - [ ] EXPLAIN 재분석
- after_query1_explain.json (함수 사용, 여전히 느림) - after_query1_explain.json (함수 사용, 여전히 느림)
@@ -67,10 +67,10 @@
스테이징 테스트 성공 후: 스테이징 테스트 성공 후:
1. **260915-improve-production 디렉토리 생성** 1. **260915-improve-production 디렉토리 생성**
- 동일한 구조 (01-baseline.md ~ 04-checklist.md) - 동일한 구조 (02-baseline.md ~ 04-checklist.md)
- 새벽 2시에 실행 - 새벽 2시에 실행
2. **02-add-indexes.md 수정** 2. **03-add-indexes.md 수정**
- 스테이징 결과 참고 - 스테이징 결과 참고
- 운영 DB 스크립트 작성 - 운영 DB 스크립트 작성
+25 -14
View File
@@ -6,13 +6,14 @@
## 📋 문서 구조 ## 📋 문서 구조
| # | 파일 | 설명 | | # | 파일 | 설명 | 소요시간 |
|---|---|---| |---|---|---|---|
| 00 | `00-overview.md` | 전체 계획 및 사전 확인 | | 00 | `00-overview.md` | 전체 계획 및 사전 확인 | - |
| 01 | `01-baseline.md` | **현재 상태 측정** (EXPLAIN, 실행 시간) | | 01 | `01-premeasure.md` | 🔷 **먼저 이것!** 테이블 크기, 중복 확인, EXPLAIN 기준값 | 20분 |
| 02 | `02-add-indexes.md` | **인덱스 추가 실행** | | 02 | `02-baseline.md` | **개선 전 성능 측정** (EXPLAIN, 실행 시간) | 15분 |
| 03 | `03-verify.md` | **개선 효과 검증** (EXPLAIN, 성능 비교) | | 03 | `03-add-indexes.md` | **인덱스 추가 실행** | 5분 |
| 04 | `04-checklist.md` | **최종 체크리스트** (성공 기준) | | 04 | `04-verify.md` | **개선 후 성능 측정 및 비교** (EXPLAIN, 성능 비교) | 15분 |
| 05 | `05-checklist.md` | **최종 체크리스트** (성공 기준) | 10분 |
--- ---
@@ -21,13 +22,23 @@
### 스테이징 DB에서 테스트 (Synology) ### 스테이징 DB에서 테스트 (Synology)
```bash ```bash
# 1. 00-overview.md 읽기 # 00. 00-overview.md 읽기
# 2. 01-baseline.md 실행 (15분)
# 3. 02-add-indexes.md 실행 (5분)
# 4. 03-verify.md 실행 (15분)
# 5. 04-checklist.md 검증 (10분)
# 총 소요 시간: 약 1시간 # 01. 🔷 01-premeasure.md 실행 (20분)
# → 테이블 크기, 중복, EXPLAIN 기준값 저장
# 02. 02-baseline.md 실행 (15분)
# → 개선 전 성능 측정, 파일 저장
# 03. 03-add-indexes.md 실행 (5분)
# → 인덱스 추가
# 04. 04-verify.md 실행 (15분)
# → 개선 후 성능 측정, 비교
# 05. 05-checklist.md 검증 (10분)
# 총 소요 시간: 약 1시간 15분
``` ```
--- ---
@@ -94,6 +105,6 @@ doc/plan/db/260915-improve-stage/
## 다음 단계 ## 다음 단계
1. **지금:** 01-baseline.md부터 시작 1. **지금:** 01-premeasure.md부터 시작
2. **스테이징 완료 후:** 260915-improve-production 디렉토리 생성 2. **스테이징 완료 후:** 260915-improve-production 디렉토리 생성
3. **운영 서버:** 동일한 절차 (새벽 2시) 3. **운영 서버:** 동일한 절차 (새벽 2시)