|
프롤로그. 느린 쿼리의 시간 지도
1장. 성능 튜닝을 어렵게 만드는 첫 번째 오해 1절. 빠른 SQL보다 먼저 필요한 비용 감각 2절. 응답 시간이 길어지는 네 개의 층 3절. 추측 대신 측정으로 들어가는 출발점 4절. 초보 백엔드 개발자의 성능 노트 2장. 테이블 스캔과 실행계획의 기본 문법 1절. 한 줄을 찾으려다 전부 읽는 구조 2절. 선택도와 카디널리티의 숨은 영향 3절. 통계가 낡을 때 생기는 엉뚱한 계획 4절. 작은 테이블과 큰 테이블의 다른 기준 3장. 인덱스가 빠른 길이 되는 조건 1절. B-트리와 탐색 범위의 축소 2절. 복합 인덱스의 앞열 규칙 3절. 조건문과 인덱스 포기 4절. 읽기 속도 뒤의 쓰기 비용 4장. 조인 순서와 데이터 폭의 실제 비용 1절. 조인을 느리게 만드는 행 수 폭발 2절. 중첩 루프·해시·머지 조인의 선택 기준 3절. 조인 키와 외래키가 만드는 차이 4절. 필요한 열만 가져오는 습관 5장. 정렬과 그룹화가 만드는 임시 작업장 1절. ORDER BY 뒤에 숨어 있는 파일 정렬 2절. GROUP BY와 DISTINCT의 중복 제거 비용 3절. 메모리 부족과 디스크 임시공간 4절. 인덱스로 정렬을 줄이는 설계 6장. 페이지네이션의 뒤쪽 페이지 함정 1절. OFFSET이 뒤로 갈수록 느려지는 이유 2절. 커서 기반 페이지네이션의 작동 원리 3절. 정렬 기준과 고유값의 짝 4절. 무한 스크롤과 관리자 목록의 다른 해법 7장. N+1 문제와 애플리케이션의 반복 호출 1절. 한 번의 화면이 수백 번의 쿼리로 변하는 순간 2절. ORM의 편리함과 숨은 왕복 비용 3절. 조인 로딩과 배치 로딩의 선택 4절. 로그에서 반복 패턴을 잡는 방법 8장. 트랜잭션과 잠금이 가려 놓는 대기 시간 1절. 느린 쿼리보다 무서운 기다리는 쿼리 2절. 읽기와 쓰기가 서로 막히는 구조 3절. 인덱스 부재가 잠금을 키우는 이유 4절. 짧은 트랜잭션과 재시도 설계 9장. 커넥션 풀과 캐시의 양날 1절. 연결 수가 많을수록 빨라진다는 착각 2절. 풀 고갈이 응답 시간을 밀어 올리는 흐름 3절. 캐시 적중과 오래된 데이터의 경계 4절. 캐시가 느린 쿼리를 숨기는 문제 10장. 쓰기 성능과 읽기 성능의 교환 1절. 인덱스가 늘수록 INSERT가 무거워지는 이유 2절. 대량 업데이트와 배치 처리의 균형 3절. 정규화와 반정규화의 실전 판단 4절. 읽기 모델과 쓰기 모델의 분리 11장. 성능 문제를 재현하는 개발자의 습관 1절. 개발 환경에서 빠른 쿼리의 함정 2절. 실제 데이터 크기와 분포의 재현 3절. 슬로 쿼리 로그와 실행계획 저장법 4절. 수정 전후를 같은 조건으로 비교하는 기준 12장. 느린 쿼리를 팀의 기준으로 다루는 법 1절. 코드 리뷰에 들어가야 할 SQL 질문 2절. 인덱스 추가 요청서의 핵심 문장 3절. 장애 전조를 읽는 지표와 알림 4절. 성능 지식을 팀의 언어로 남기는 방법 에필로그. 시간을 읽는 개발자의 다음 작업 |
|
느린 SQL 한 줄은 사용자에게는 멈춘 화면으로, 운영팀에는 장애 알림으로, 조직에는 보이지 않는 비용으로 돌아온다. 그런데 많은 팀이 실행계획 한 장이나 인덱스 하나에만 매달린 채 진짜 병목을 놓친다. 데이터베이스는 요청 경로의 한 구간일 뿐이며, 애플리케이션 호출 횟수와 잠금 대기, 연결 풀, 캐시, 네트워크가 함께 응답 시간을 만든다.
《SQL 성능의 뒷문》은 성능 튜닝을 감각과 경험담에서 꺼내 측정 가능한 작업으로 바꾼다. 실행계획, 인덱스, 조인, 정렬과 집계, 페이지네이션을 기본 축으로 삼고, N+1과 트랜잭션, 잠금, 캐시까지 이어지는 병목의 연쇄를 보여 준다. 빠른 읽기가 느린 쓰기를 만들 수 있고, 한 화면의 개선이 전체 시스템 비용을 키울 수 있다는 교환 관계도 놓치지 않는다. 무엇보다 이 책은 답보다 절차를 남긴다. 재현 조건, 기준선, 변경 단위, 회귀 확인, 팀 리뷰 문장을 고정하면 성능 문제는 특정 고수의 직감이 아니라 조직이 반복할 수 있는 기술이 된다. 쿼리를 고쳐도 같은 장애가 돌아왔다면, 이제 문장 앞뒤의 시간을 함께 보아야 한다. 오늘의 임시 처방을 내일의 운영 기준으로 바꾸고 싶은 개발자라면 가장 먼저 펼쳐야 할 책이다. |