사용자 한 분이 "주문 내역 페이지가 가끔 5초씩 걸려요"라는 메일을 보냈다. 로컬에서는 0.3초. 이런 문제는 대개 추측으로 고치려다 시간을 버린다. 이번에는 재는 것부터 시작했다.
1. 느린 요청부터 모은다
PHP-FPM의 슬로우 로그를 켜면 일정 시간 넘게 걸린 요청의 호출 스택을 남겨 준다. 설정은 두 줄이면 된다.
; /etc/php/8.1/fpm/pool.d/www.conf
request_slowlog_timeout = 2s
slowlog = /var/log/php-fpm/slow.log하루 동안 모아 보니 느린 요청의 90%가 같은 함수에서 멈춰 있었다. 주문 목록을 돌면서 상품 정보를 하나씩 가져오는 곳이다.
2. 숫자로 확인한다
| 측정 지점 | 평균 | 최대 |
|---|---|---|
| 전체 요청 | 1,840ms | 5,210ms |
| DB 쿼리 합계 | 1,520ms | 4,800ms |
| 템플릿 렌더링 | 95ms | 160ms |
| 나머지 | 225ms | 250ms |
평균만 보면 안 됩니다. 사용자가 느끼는 건 최댓값과 상위 5%입니다.
3. 범인은 반복문 속 쿼리
주문이 많은 사용자일수록 느렸다. 전형적인 N+1 문제다. 다음 편에서 이걸 어떻게 한 번의 쿼리로 줄였는지 적는다.
측정하지 않은 최적화는 기도와 같다.
어느 개발자의 책상 메모
코드 한 줄
