← 전체 글로 돌아가기

웹 개발

웹 서비스 운영 중 리스트 페이지가 갑자기 느려지면

운영 환경에서 리스트 페이지의 성능이 저하되었을 때 원인을 찾고 개선하는 단계별 방법을 정리했다.

어느 날 갑자기 리스트 페이지가 느려진다면, 보통 트래픽 증가, 데이터 증가, 혹은 쿼리 성능 저하가 원인이다.

서버 리소스 상태 확인하기

가장 먼저 서버의 CPU, 메모리, 디스크 사용률을 확인하자. top 명령이나 모니터링 대시보드를 열어보면 현재 서버가 얼마나 바쁜지 알 수 있다. CPU가 100%라면 해당 프로세스가 뭔지 찾아야 하고, 메모리가 거의 다 찼다면 메모리 누수가 있을 수 있다.

top
free -h
df -h

데이터베이스 쿼리 성능 확인하기

리스트 페이지가 느리다면 보통 데이터베이스 쿼리 때문이다. 데이터베이스에서 EXPLAIN 명령을 사용해서 쿼리 실행 계획을 확인하자. 풀 테이블 스캔을 하고 있지는 않은지, 필요한 인덱스가 있는지 살펴보자.

데이터 개수 확인하기

몇 개월 전에는 데이터가 10만 개였는데, 지금은 1000만 개가 되었을 수도 있다. 전체 데이터를 한 번에 로드하는 쿼리는 당연히 느려진다. 페이지네이션이나 무한 스크롤을 제대로 구현했는지 확인하자.

SELECT COUNT(*) FROM items;

인덱스 확인하고 추가하기

자주 사용되는 필터나 정렬 기준이 인덱스되어 있는지 확인하자. 예를 들어 사용자가 created_at 기준으로 정렬하는데 인덱스가 없다면, 새 인덱스를 추가해야 한다. 인덱스 생성은 시간이 걸릴 수 있으니 조심해서 진행하자.

N+1 쿼리 문제 찾기

리스트의 각 아이템마다 추가 쿼리를 실행하고 있지는 않은지 확인하자. 예를 들어 사용자 100명을 조회한 뒤, 각 사용자의 주문을 따로 조회한다면 100개의 추가 쿼리가 나간다. JOIN을 사용하거나 배치 로딩으로 개선할 수 있다.

캐싱 활용하기

자주 조회되는 리스트를 캐싱하면 성능이 크게 향상된다. Redis를 사용하거나, 메모리 캐시를 구현할 수 있다. 다만 캐시 만료(TTL)를 적절하게 설정해야 최신 데이터를 보여줄 수 있다.

API 응답 크기 줄이기

필요 없는 필드까지 모두 응답에 포함시키고 있지는 않은지 확인하자. 특히 각 아이템에 긴 텍스트나 이미지 URL이 많다면, 응답 크기가 커서 브라우저 렌더링도 느려진다. 클라이언트에서 정말 필요한 필드만 요청하거나, 서버에서 필드를 선택적으로 반환하는 기능을 추가하자.

작은 변화를 기록해두기

성능 문제를 해결했다면, 어떤 변경이 효과가 있었는지 기록해두자. 다음에 비슷한 문제가 생겼을 때 이전 경험을 참고할 수 있다. 모니터링을 설정해두면 성능 저하를 미리 감지할 수 있다.