Search

[권장:성능]페이징 전 조인

BAD: 139.620ms, hit=65663

페이징 이전에 상세 조인
SELECT o.ord_no ,o.ord_dtm ,m.mbr_id ,m.nick_nm ,s.shop_id ,s.shop_nm ,c1.base_cd_nm AS ord_st_nm ,c2.base_cd_nm AS pay_tp_nm FROM startdbpg.tr_ord_big o LEFT OUTER JOIN startdbpg.ms_mbr_big m ON (m.mbr_id = o.mbr_id) LEFT OUTER JOIN startdbpg.ms_shop_big s ON (s.shop_id = o.shop_id) LEFT OUTER JOIN startdbpg.cm_base_cd c1 ON (c1.base_cd_dv = 'ord_st' AND c1.base_cd = o.ord_st) LEFT OUTER JOIN startdbpg.cm_base_cd c2 ON (c2.base_cd_dv = 'pay_tp' AND c2.base_cd = o.pay_tp) WHERE o.ord_dtm >= '2024-01-01' AND o.ord_dtm < '2024-02-01' ORDER BY o.ord_dtm DESC, o.ord_no DESC LIMIT 100 OFFSET 30000 ;
SQL
복사
실행계획 보기
•
301페이지를 보여 주려고, 앞 페이지까지 포함한 30,100건을 회원·매장·코드와 모두 조인한 뒤 앞 30,000건을 버립니다.
•
페이지가 뒤로 갈수록 조인 건수가 계속 늘어납니다.

GOOD: 16.959ms, hit=1275

페이징 후 필요한 행만 조인
SELECT o.ord_no ,o.ord_dtm ,m.mbr_id ,m.nick_nm ,s.shop_id ,s.shop_nm ,c1.base_cd_nm AS ord_st_nm ,c2.base_cd_nm AS pay_tp_nm FROM ( SELECT o1.ord_no ,o1.ord_dtm ,o1.ord_st ,o1.pay_tp ,o1.mbr_id ,o1.shop_id FROM startdbpg.tr_ord_big o1 WHERE o1.ord_dtm >= '2024-01-01' AND o1.ord_dtm < '2024-02-01' ORDER BY o1.ord_dtm DESC ,o1.ord_no DESC LIMIT 100 OFFSET 30000 ) o LEFT OUTER JOIN startdbpg.ms_mbr_big m ON (m.mbr_id = o.mbr_id) LEFT OUTER JOIN startdbpg.ms_shop_big s ON (s.shop_id = o.shop_id) LEFT OUTER JOIN startdbpg.cm_base_cd c1 ON (c1.base_cd_dv = 'ord_st' AND c1.base_cd = o.ord_st) LEFT OUTER JOIN startdbpg.cm_base_cd c2 ON (c2.base_cd_dv = 'pay_tp' AND c2.base_cd = o.pay_tp) ORDER BY o.ord_dtm DESC, o.ord_no DESC ;
SQL
복사
실행계획 보기
•
보여 줄 100건만 먼저 고르고, 그 100건만 조인합니다.
•
몇 번째 페이지든 조인은 항상 100건입니다.
💡

KEY POINT

•
페이징 SQL은 페이지에 보여 줄 행만 먼저 고르고, 그다음에 조인합니다.
•
조인한 뒤 페이징하면 OFFSET까지 포함한 행을 모두 조인하므로, 뒤 페이지로 갈수록 느려집니다.
•
안쪽에서 페이징한 뒤에도 바깥에 ORDER BY를 다시 씁니다.
✏️

TIP. 먼저 페이징할 수 없는 경우

•
조인 결과로 행이 걸러지거나 늘어나면 먼저 페이징할 수 없습니다. 예를 들어 조인한 테이블의 조건으로 주문을 거르는 INNER JOIN이라면, 페이징 후 조인하면 페이지마다 건수가 모자랍니다.
•
이 방식은 지금처럼 LEFT OUTER JOIN이고, 주문 1건에 1건씩 붙을 때 씁니다.
📖 DEEP DIVE
🔗