Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions src/content/cases/purple-search.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ order: 1
title: "주문 ID를 먼저 골라 검색 SQL 비용 줄이기"
summary: "관리자 주문 검색이 주문마다 관련 테이블을 반복 확인해 느렸습니다. 검색어에 맞는 주문 ID를 먼저 모으는 방식으로 바꿔, 원번 검색의 count SQL을 4.73초에서 0.89초로 줄였습니다."
role: "주문 검색 SQL 개선, 환불요청 검색 연결, 변경 전후 결과 대조"
decision: "주문 테이블의 직접 검색 조건은 유지하고, 관련 테이블 검색만 별도 UNION 쿼리로 분리해 주문 ID를 먼저 모았습니다."
decision: "실행 계획과 측정으로 정렬은 병목이 아님을 확인해 인덱스는 추가하지 않았습니다. 대신 검색어에 맞는 주문 ID를 별도 쿼리로 먼저 모아, 바깥 쿼리가 PK 조회만 하게 바꿨습니다."
tradeoff: "SQL 왕복과 ID 전달 비용이 생깁니다. 결과가 넓게 걸리는 1글자 검색은 1.86초에서 1.95초로 조금 느려졌습니다."
diagram: query
diagramCaption: "관련 테이블에서 검색어에 맞는 주문 ID를 먼저 모읍니다. 목록과 count는 그 ID를 함께 씁니다."
Expand All @@ -15,11 +15,25 @@ sources: []

관리자 주문 검색은 회원·상품·결제 조건을 주문마다 상관 서브쿼리로 확인했습니다. 조회 기간이 길수록 이 반복 비용이 커져, 전체 기간에서 원번으로 검색하면 count SQL만 4.73초가 걸렸습니다.

### 내 기여와 해결
### 해결 과정

관련 테이블에서 검색어에 맞는 주문 ID를 **별도 UNION 쿼리로 먼저 모으고**, 바깥 쿼리는 그 ID로만 조회하도록 바꿨습니다. 주문 테이블 자체의 검색 조건은 그대로 두었습니다.
**1. 실행 계획 확인**

한 SQL 안에 넣는 방식도 검토했지만, MySQL이 서브쿼리를 다시 주문마다 실행해 반복 비용이 남았습니다. 그래서 SQL 왕복이 하나 늘더라도 ID 선별을 분리했습니다. 검색 안내 문구에는 있었지만 실제로 연결되지 않았던 환불요청 검색도 함께 연결했습니다.
먼저 `EXPLAIN`을 돌렸습니다. 주문 테이블 전체를 훑으면서(`type: ALL`), 관련 테이블 조건마다 `DEPENDENT SUBQUERY`가 7개 붙어 있었습니다. 주문 한 건마다 서브쿼리가 다시 실행되는 구조였습니다.

**2. 인덱스 확인**

주문 테이블에 생성일·유형 인덱스가 없어 정렬(filesort)이 생기는 것도 보였습니다. 하지만 정렬 없는 count(0.55초)와 정렬한 목록 20건(0.49초)이 거의 같아, **정렬은 병목이 아니라고 보고 인덱스는 추가하지 않았습니다.**

**3. 한 SQL 안에서 ID 먼저 고르기**

`o.id IN (SELECT … UNION …)` 형태로 바꿔 봤습니다. 그런데 MySQL이 이를 다시 `DEPENDENT SUBQUERY`/`DEPENDENT UNION`으로 실행해 실행 계획이 원래와 같았고, 시간도 4.55초로 그대로였습니다.

**4. 쿼리를 둘로 나누기**

검색어에 맞는 주문 ID를 **별도 쿼리로 먼저 모으고**, 바깥 쿼리는 그 ID로 PK 조회만 하게 했습니다. SQL 왕복은 한 번 늘었지만 원번 검색은 **0.33초 + 0.56초 = 0.89초**가 됐습니다.

주문 테이블 자체의 검색 조건은 그대로 두었고, 검색 안내 문구에는 있었지만 실제로 연결되지 않았던 환불요청 검색도 함께 연결했습니다.

### 측정

Expand Down
Loading