개발자 팁SQL 팁 › 느린 쿼리를 찾는 순서 — 감이 아니라 로그에서 시작한다

느린 쿼리를 찾는 순서 — 감이 아니라 로그에서 시작한다

2026-08-28 · SQL 팁
한 줄 요약

어디가 느린지 추측하지 않고 측정으로 좁히는 절차. slow query log부터 실행 계획까지.

감으로 시작하면 엉뚱한 곳을 고친다

"이 화면이 느리다"에서 곧바로 특정 쿼리를 의심하는 것은 대개 빗나간다. 순서를 지키면 훨씬 빠르다.

1단계 — 슬로우 쿼리 로그

DB가 제공하는 기능부터 켠다.

```

MySQL

slow_query_log = ON

long_query_time = 1

PostgreSQL

log_min_duration_statement = 1000 # ms

```

기준값은 1초에서 시작해 상황에 따라 낮춘다. 처음부터 100ms로 잡으면 로그가 폭증한다.

2단계 — 총 소요 시간으로 정렬

가장 흔한 실수가 가장 느린 한 건을 먼저 고치는 것이다. 실제로 중요한 것은 총합이다.

```

쿼리 A: 5초 × 하루 10회 = 50초

쿼리 B: 0.1초 × 하루 50,000회 = 5,000초

```

B가 100배 더 큰 문제인데, 로그를 시간 순으로만 보면 A가 눈에 띈다.

pg_stat_statements(PostgreSQL)나 performance_schema(MySQL) 같은 집계 뷰를 쓰면 이 정렬을 바로 볼 수 있다.

3단계 — 실행 계획

대상을 정했으면 계획을 본다.

```sql

EXPLAIN ANALYZE SELECT ...;

```

확인할 것:

4단계 — 원인별 대응

| 관찰 | 대응 |

|---|---|

| 통계 부정확 | 통계 갱신 (ANALYZE) |

| 인덱스 미사용 | 조건절 형태 확인 (함수·타입) |

| 인덱스 없음 | 추가 검토 (쓰기 비용 고려) |

| 조인 순서 문제 | 조건 재작성, 필요시 힌트 |

| 결과 자체가 큼 | 페이지네이션·필터 추가 |

| 정렬이 비쌈 | 정렬 컬럼 인덱스 검토 |

마지막 두 행이 자주 간과된다. 쿼리가 느린 게 아니라 가져오는 데이터가 너무 많은 경우, 인덱스로는 해결되지 않는다.

인덱스를 추가하기 전에

인덱스는 공짜가 아니다.

추가 전 확인:

  1. 기존 인덱스로 커버되지 않는가 (복합 인덱스의 선행 컬럼)
  2. 이 쿼리가 실제로 자주 실행되는가
  3. 조건의 선택도가 충분한가

5단계 — 재측정

고친 뒤 같은 방식으로 다시 잰다. 계획만 보고 "좋아졌겠지"로 끝내면 안 된다.

애플리케이션 쪽 원인

DB 쪽에서 아무 문제가 없는데 화면이 느린 경우도 흔하다.

슬로우 쿼리 로그가 비어 있다면 이쪽을 본다. APM 도구로 요청 전체의 시간 분포를 보면 어디서 시간이 가는지 드러난다.

최종 수정 2026-08-28

자주 묻는 질문

슬로우 쿼리 기준을 몇 초로 잡나요?

서비스 특성에 따라 다르지만 1초에서 시작해 점차 낮추는 방식이 흔합니다.

한 번 느린 쿼리와 자주 느린 쿼리 중 무엇을 먼저 봐야 하나요?

총 소요 시간(횟수 × 평균)이 큰 쪽이 우선입니다. 0.1초 쿼리가 만 번 나가면 1000초입니다.

인덱스 추가가 항상 답인가요?

아닙니다. 쓰기 비용과 저장 공간이 늘고, 이미 있는 인덱스와 중복되는 경우도 있습니다.

DB Linker로 지금 시작하기

AI 채팅으로 데이터베이스를 조회·관리하는 로컬 전용 개발자 도구. 자체 서버 없이 이용자의 기기에서만 동작합니다.

App Store에서 받기 →

안내

이 글은 일반적인 데이터베이스 관리 원칙과 개발 관행을 다루는 콘텐츠이며, 특정 프로젝트·프로덕션 환경에 대한 전문적 조언을 대체하지 않습니다. 구체적 버전·수치가 언급되더라도 실제 사용 중인 도구·버전에서 반드시 재확인하시기 바랍니다.

글 중 일부는 AI 도구의 도움을 받아 초안을 작성한 뒤 발행됩니다. 내용 중 사실과 다르거나 수정이 필요한 부분을 발견하시면 GitHub Issues로 알려주세요.