성능 개선 기록에서 내가 오래 남기고 싶은 숫자는 조회한 행이 1,922개에서 64개로 줄었다는 사실이다. 그런데 숫자만 떼어내면 중요한 절반이 빠진다. 당시 두 기관명 검색의 결과 8건과 3건을 유지했다는 확인이 함께 있었다.
전체 기사 문자열을 비교하던 방식에서 기존 전문검색과 기관명 색인을 활용하는 방향으로 바꾼 작업이었다. 그것은 결과를 대충 줄여 빨라진 사례가 아니라, 필요한 답으로 가는 길을 좁힌 사례였다. 이 수치는 2026년 9월의 해당 조건에서 확인한 결과다.
검색하는 사람의 답을 먼저 보존한다
나는 비용을 줄이기 위해 필요한 결과까지 사라지는 홈페이지를 만들고 싶지 않다. 고객에게 같은 정보를 전달하면서 서버가 덜 돌아가게 하는 개선과, 보여주는 정보를 줄이는 개선은 다른 선택이다. 두 선택을 정확히 설명한다.
내가 먼저 보존하는 것
- 비교할 검색어와 데이터 시점을 고정한다.
- 결과 ID뿐 아니라 정렬 순서, 페이지 이동, 누락된 값 처리도 기록한다.
- 최적화 전후의 조회한 행 수, CPU와 응답 결과를 같은 조건으로 비교한다.
- 빈 결과, 결과가 많은 조건, 다른 언어와 날짜 경계를 함께 검사한다.
작은 합성 예제로 쿼리 계획 읽기
아래 예제는 실제 운영 스키마가 아니다. 해당 조건으로 자주 조회한다는 가정 아래 복합 색인을 검토하는 방법을 보여준다. 읽기를 줄이는 이점과 추가 쓰기·저장 비용을 함께 평가한다.
코드와 구현 살펴보기
합성 SQLite/D1 예제 · 자체 스키마에 맞춰 검토
CREATE TABLE notes (
id INTEGER PRIMARY KEY,
organization TEXT NOT NULL,
published_at TEXT NOT NULL,
title TEXT NOT NULL
);
CREATE INDEX idx_notes_org_date
ON notes(organization, published_at DESC, id DESC);
EXPLAIN QUERY PLAN
SELECT id, title, published_at FROM notes
WHERE organization = 'Example Institute'
ORDER BY published_at DESC, id DESC
LIMIT 20;계획이 좋아도 실제 결과를 다시 확인한다
색인이 존재한다고 모든 쿼리에 쓰이는 것은 아니다. 필터 조건과 정렬이 색인의 구조에 맞는지 계획에서 확인하고, 실제 읽기 지표를 대조한다. 앞에 와일드카드가 붙은 문자열 검색은 같은 방법으로 해결된다고 가정하지 않는다.
표시할 열만 가져오는 일, 목록과 상세를 분리하는 일, 운영 요청에서 스키마 변경을 빼는 일도 검토할 수 있다. 가장 자주 실행되는 비싼 쿼리부터 손보되 의미를 바꾸는 변경은 별도로 설명한다.
내가 남기는 성능 기록
‘빨라졌다’ 대신 데이터 조건, 전후 쿼리, 계획, 결과 비교, 관찰 구간을 한 묶음으로 남긴다. 결과를 유지한 개선과 결과 범위를 줄인 개선을 구별하면 다음 사람이 그 선택을 이어갈 수 있다.