Skip to content
튜닝 연습서브쿼리와 쿼리 변환
SUBQ-048

상품 수불 화면의 「발주」 탭이 57블록짜리 발주상품을 보는데 판매상품 110만 줄을 읽는다

기초DDL유통283 / 700

상황 ​

상품팀의 「상품 수불」 화면에는 판매, 반품, 발주, 입출고 탭이 있다. 탭을 고르면 공통 뷰 V_ITM_MOVE에서 그 구분(MV_TP)만 골라 읽는다. 「발주」 탭은 상품 하나의 발주 65줄을 보여 주는데 0.1초 가까이 걸린다. 발주상품 테이블은 57블록뿐인데 이상하다는 문의가 왔고, 「입출고」 탭을 열 때는 판매상품 테이블을 읽지 않는다는 것도 함께 알려 왔다.

테이블과 인덱스 ​

  • CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · SLE_QTY는 NOT NULL이고 반품은 수량이 음수로 들어간다
  • CF13 발주상품: 7,102행 · 57블록 · PK (ORD_NO, ITM_NO)
  • CF15 입출고상품: 51,497행 · 349블록 · PK (INOUT_NO, ITM_NO)
  • 세 테이블 모두 ITM_NO가 선두인 인덱스는 없다 · 상품 109개 · 아래 상품의 발주 65줄 · 통계 최신

원본 SQL ​

sql
-- 공통 뷰: 상품 수불
CREATE OR REPLACE VIEW V_ITM_MOVE AS
SELECT ITM_NO,
       CASE WHEN SLE_QTY < 0 THEN 'RTN' ELSE 'SLE' END AS MV_TP,
       SLE_NO AS REF_NO, SLE_QTY AS QTY
  FROM CF11
UNION ALL
SELECT ITM_NO, 'ORD', ORD_NO, ORD_QTY
  FROM CF13
UNION ALL
SELECT ITM_NO, 'IO', INOUT_NO, INOUT_QTY
  FROM CF15;

-- 상품 수불 화면 (탭마다 :tp 만 바뀐다)
SELECT REF_NO, QTY
  FROM V_ITM_MOVE
 WHERE ITM_NO = :itm
   AND MV_TP  = :tp;

실행계획 학습용 예시 ​

xplan
[:tp = 'ORD']
--------------------------------------------------------------------------------------------
| Id  | Operation            | Name       | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |            |      1 |        |     65 |00:00:00.08 |    8261 |
|   1 |  VIEW                | V_ITM_MOVE |      1 |    638 |     65 |00:00:00.08 |    8261 |
|   2 |   UNION-ALL          |            |      1 |        |     65 |00:00:00.08 |    8261 |
|*  3 |    TABLE ACCESS FULL | CF11       |      1 |    101 |      0 |00:00:00.08 |    8204 |
|*  4 |    FILTER            |            |      1 |        |     65 |00:00:00.01 |      57 |
|*  5 |     TABLE ACCESS FULL| CF13       |      1 |     65 |     65 |00:00:00.01 |      57 |
|*  6 |    FILTER            |            |      1 |        |      0 |00:00:00.01 |       0 |
|*  7 |     TABLE ACCESS FULL| CF15       |      0 |    472 |      0 |00:00:00.01 |       0 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter(("ITM_NO"=:ITM AND CASE  WHEN "SLE_QTY"<0 THEN 'RTN' ELSE 'SLE' END =:TP))
   4 - filter(:TP='ORD')
   5 - filter("ITM_NO"=:ITM)
   6 - filter(:TP='IO')
   7 - filter("ITM_NO"=:ITM)

문제 ​

  1. 바깥 조건 MV_TP = :tp가 세 갈래에 각각 어떤 모양으로 들어갔는지 Predicate Information으로 설명하시오. 7번 줄의 Starts가 0인데 3번 줄은 1인 이유도 설명하시오.
  2. 「발주」 탭이 판매상품을 읽지 않도록 뷰를 고치시오. 고친 뷰가 다른 탭과 화면에 주는 영향도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자