---
name: typeorm-mysql-tuning-skill
description: TypeORM + MySQL 성능 튜닝 스킬. TypeORM(Node.js/TypeScript) 환경에서 MySQL 쿼리가 느린 경우, N+1 문제 해결, EXPLAIN 분석, 인덱스 설계, relations 로딩 전략, 배치 처리, QueryBuilder 최적화 등 모든 TypeORM+MySQL 성능 관련 작업에 사용한다. "N+1 쿼리가 발생해요", "TypeORM 쿼리가 느려요", "relations vs leftJoinAndSelect", "bulk insert 사용법", "synchronize 설정", "QueryBuilder 최적화" 등의 요청에 이 스킬을 사용할 것.
---

# TypeORM MySQL 성능 튜닝 스킬

## 개요

이 스킬은 TypeORM (Node.js/TypeScript) 환경에서 MySQL 쿼리 성능 문제를 진단하고 해결하는 데 필요한 레퍼런스를 제공한다. 사용자의 요청에 따라 아래 레퍼런스 파일 중 필요한 것만 선택적으로 읽어서 활용한다.

## 레퍼런스 파일 구조

| 파일 | 내용 | 이런 경우 읽을 것 |
|------|------|-------------------|
| `reference/01-explain-logging.md` | 쿼리 로깅 및 EXPLAIN 실행 | SQL 로깅 설정, getSql(), EXPLAIN, maxQueryExecutionTime |
| `reference/02-index.md` | 엔티티 인덱스 선언 및 커버링 인덱스 | @Index 데코레이터, select 제한, 선두 컬럼 원칙 |
| `reference/03-n-plus-one.md` | N+1 문제 해결 | relations, leftJoinAndSelect, 필요 컬럼만 select |
| `reference/04-query-patterns.md` | 실전 쿼리 튜닝 패턴 | 좌변 가공 방지, 형변환 방지, 서브쿼리→JOIN, Keyset 페이징, 대량 DML, 트랜잭션 |
| `reference/05-orm-pitfalls.md` | TypeORM 특유 주의사항 | find() SELECT *, eager/lazy 관계, synchronize, save() 반복 |
| `reference/06-checklist.md` | 튜닝 체크리스트 | 종합 진단, 전체 점검 |

## 사용 흐름

1. 사용자의 요청을 파악한다
2. 관련된 레퍼런스 파일을 `view` 도구로 읽는다 (여러 파일이 필요하면 복수 로드)
3. 레퍼런스의 내용을 바탕으로 구체적인 진단과 해결책을 제시한다

## 핵심 원칙

- **logging: true로 SQL 확인**: 개발 시 항상 실행 쿼리를 확인한다
- **N+1을 항상 경계**: relations 또는 leftJoinAndSelect로 명시적 로딩
- **select 제한**: find()의 SELECT * 대신 QueryBuilder로 필요 컬럼만
- **synchronize: false**: 프로덕션에서 반드시 끄고 migration 사용
- **save() 반복 금지**: insert().values()로 배치 처리

## 빠른 진단 가이드

사용자가 "TypeORM 쿼리가 느려요" 라고 말하면, 이 순서로 진단한다:

```
1. SQL 로깅 켜기 → 01-explain-logging.md
   - logging: true로 실제 쿼리 확인
   - maxQueryExecutionTime으로 슬로우 쿼리 감지

2. N+1 문제인가? → 03-n-plus-one.md
   - lazy/eager 설정 확인
   - relations / leftJoinAndSelect 적용

3. 인덱스 문제인가? → 02-index.md
   - @Index 선언 확인
   - 커버링 인덱스 / select 제한

4. 쿼리 패턴 문제인가? → 04-query-patterns.md
   - 좌변 함수? 형변환? OFFSET 페이징?

5. TypeORM 특유 함정인가? → 05-orm-pitfalls.md
   - synchronize: true? save() 반복? eager: true?
```
