BAD: 177.446ms, hit=129973, read=597
같은 테이블을 반복 조회
SELECT o.ord_dtm
,o.ord_no
,o.mbr_id
,(SELECT MAX(x1.nick_nm) FROM startdbpg.ms_mbr_big x1 WHERE x1.mbr_id = o.mbr_id) nick_nm
,(SELECT MAX(x2.mbr_gd) FROM startdbpg.ms_mbr_big x2 WHERE x2.mbr_id = o.mbr_id) mbr_gd
FROM startdbpg.tr_ord_big o
WHERE o.ord_dtm >= '2024-01-01'
AND o.ord_dtm < '2024-01-02'
ORDER BY o.ord_no
;
SQL
복사
실행계획 보기
•
주문 21,708건마다 회원 테이블을 2번씩, 총 43,416번 찾아갑니다(SubPlan마다 loops=21708).
•
같은 회원 행을 두 번 읽어서 컬럼을 하나씩 가져오는 셈입니다.
GOOD: 73.465ms, hit=1574
한 번 조인하여 컬럼 조회
SELECT o.ord_dtm
,o.ord_no
,o.mbr_id
,m.nick_nm
,m.mbr_gd
FROM startdbpg.tr_ord_big o
LEFT OUTER JOIN startdbpg.ms_mbr_big m
ON (m.mbr_id = o.mbr_id)
WHERE o.ord_dtm >= '2024-01-01'
AND o.ord_dtm < '2024-01-02'
ORDER BY o.ord_no
;
SQL
복사
실행계획 보기
•
회원 테이블을 한 번만 읽어 주문에 붙이고, 필요한 컬럼을 함께 가져옵니다.
•
mbr_id는 회원 테이블의 PK라 1건만 붙습니다. 스칼라 서브쿼리처럼 회원이 없으면 NULL이 나오도록 LEFT OUTER JOIN을 씁니다.
KEY POINT
•
같은 테이블을 스칼라 서브쿼리로 여러 번 조회하면, 결과 행마다 그 횟수만큼 반복해서 읽습니다.
•
같은 테이블에서 여러 컬럼이 필요하면 한 번 조인해서 가져옵니다.
•
바꿀 때는 LEFT OUTER JOIN을 쓰고, 조인 대상이 1건(PK 조인)인지 확인합니다.
TIP. 스칼라 서브쿼리를 전부 없애라는 뜻은 아닙니다
•
새로 작성할 때는 조인을 권장합니다.
•
이미 있는 SQL을 무리하게 바꾸다가 로직 오류가 생길 수 있습니다. 성능 영향이 큰 SQL부터 골라서 고칩니다.
DEEP DIVE — SQL TUNER for PostgreSQL 기본원리편


