Skip to content
isdnetworks
Go back

조회 경로를 정하는 컬럼

(수정됨)

배치용 월별 조회 GET /orders/monthly 를 설계하면서 이번 달이라는 말의 기준부터 정해야 했다. 후보 컬럼들이 orders 와 order_items 어느 쪽에 있는지를 먼저 확인했다.

Table of contents

Open Table of contents

배경 — 컬럼 위치가 만든 제약

paid_at 이 order_items 에 없고 orders 에만 있었다. 결제일로 조회하려면 JOIN 이 필요하고 하위 단독으로는 못 한다는 뜻이다.

같이 확인하니 총 구매 금액과 supplier_name 과 category_code 도 하위에 없어서 계산이나 조인이 필요했다. 조인이나 계산이 필요한 것들을 목록으로 만들어 두니 설계에서 무엇을 어떻게 가져올지가 정해졌다.

원인 — 인덱스가 만든 경로

SHOW INDEX 로 보니 confirmed_at 과 created_at 에는 있고 paid_at 은 컬럼 자체가 없으니 당연히 없었다. 월 단위 범위 조회는 confirmed_at 이나 created_at 으로 가능하다는 뜻이다.

여기서 설계가 두 축으로 갈렸다. 두 가지 방법이 있었는데 하나의 엔드포인트에 기준 파라미터를 받는 것과 용도별로 둘로 나누는 것이다. 뒤쪽을 골랐다. 이유는 매출은 결제 시점에 잡히므로 리포트 집계가 paid_at 을 쓰고 정산 미반영은 정산 계산 코드가 confirmed_at 을 쓰며 하위에 인덱스도 있어서 조회 경로 자체가 달라서다. 대신 엔드포인트가 둘이 되어 배치 쪽 호출 코드도 둘로 갈리는 것을 감수했다.

주의 — 경계 행이 달라지는 문제

용도가 다르면 축도 다르다는 것에서 조심할 것이 나왔다. 확정일로 좁히면 결제일 기준 월 경계에 걸친 행이 누락될 수 있다.

한 달 말에 결제되고 다음 달 초에 확정된 건은 기준에 따라 다른 달로 들어간다. 어느 기준으로 세는지를 먼저 정하지 않으면 나중에 숫자가 안 맞고 그 원인을 찾기 어렵다.

검증 — 정밀한 조건과 성능

정산 미반영을 찾는 조건이 여럿이라 느리지 않을지 걱정했다. EXPLAIN 을 보니 confirmed_at 인덱스로 range 스캔을 하고 나머지 조건은 Using where 로 그 안에서 필터로 처리되고 있었다.

풀스캔이 없으므로 정밀한 조건이 단순한 것보다 느려지지 않는다. 인덱스가 범위를 좁히고 나머지는 그 안에서 거르므로 조건을 줄인다고 빨라지는 것이 아니다. 이 확인은 운영 데이터베이스라 실행 계획만 보고 실제 행은 읽지 않았다.

조치 — 정리한 설계

결론은 매출 조회는 orders 조인 경로를 쓰고 정산 미반영 조회는 order_items 단독으로 confirmed_at 을 쓰는 것이었다. 엔드포인트의 월 기준을 명시하거나 용도별로 나눈다.

이 조사의 요지는 어느 컬럼이 어느 테이블에 있느냐가 조회 경로를 정한다는 것이다. 설계 전에 컬럼 위치와 인덱스를 먼저 보지 않으면 이렇게 하고 싶은데 왜 느리냐는 질문에 도달하게 된다.

정리


Share this post on:

Previous Post
옮길 것이 없는 이관
Next Post
청크마다 반복되는 즉시 로딩