Skip to content
튜닝 연습조인 튜닝
JOIN-023

같은 대사 SQL이 sqlplus에서는 0.1초인데 야간 배치 안에서는 2초 가까이 걸린다

기초INSERT한빛유통173 / 700

상황 ​

야간 정산 배치의 마지막 단계는 정산과 주문을 맞대어 금액이나 고객이 다른 건을 점검 테이블에 넣는다. 정상이면 0건이다. 오과장이 SQL을 떼어 sqlplus에서 돌리면 0.1초인데, 배치 안에서는 매일 2초 가까이 걸린다. 배치 셸 스크립트 첫머리에는 ALTER SESSION 두 줄이 있고, 옆에 -- 배치가 PGA 를 다 먹어 온라인이 죽은 뒤 (2013.03)라는 주석이 달려 있다. 아래는 배치 세션에서 뜬 실행계획이다.

테이블과 인덱스 ​

  • T_ORD: 100,000행 · 896블록 · PK_T_ORD (ORD_SEQ)
  • T_ORD_STLM: 100,000행 · 640블록 · 정산 배치가 T_ORD에서 적재 · 인덱스 없음
  • T_STLM_CHK 점검 테이블 (이 문제에서 쓰는 파생 테이블): CHK_DT · ORD_SEQ · ORD_AMT · STLM_AMT · 인덱스 없음
  • 인스턴스 설정: pga_aggregate_target 512M · workarea_size_policy AUTO · 통계 최신

원본 SQL ​

sql
-- batch_stlm_chk.sh 첫머리 (2013.03)
ALTER SESSION SET workarea_size_policy = MANUAL;
ALTER SESSION SET hash_area_size = 131072;

INSERT INTO T_STLM_CHK (CHK_DT, ORD_SEQ, ORD_AMT, STLM_AMT)
SELECT TRUNC(SYSDATE), o.ORD_SEQ, o.ORD_AMT, s.STLM_AMT
  FROM T_ORD o, T_ORD_STLM s
 WHERE s.ORD_SEQ = o.ORD_SEQ
   AND (s.STLM_AMT <> o.ORD_AMT OR s.CUS_ID <> o.CUS_ID);

실행계획 학습용 예시 · 교재 06화 work area 재현 방법 ​

xplan
[배치 세션]
---------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                | Name       | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads | Writes |  OMem |  1Mem | Used-Mem | Used-Tmp|
---------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |            |      1 |        |      0 |00:00:01.87 |    1545 |  1702 |   1702 |       |       |          |         |
|   1 |  LOAD TABLE CONVENTIONAL | T_STLM_CHK |      1 |        |      0 |00:00:01.87 |    1545 |  1702 |   1702 |       |       |          |         |
|*  2 |   HASH JOIN              |            |      1 |   9950 |      0 |00:00:01.87 |    1536 |  1702 |   1702 |  6278K|  1229K|  126K (4)|    6144K|
|   3 |    TABLE ACCESS FULL     | T_ORD_STLM |      1 |    100K|    100K|00:00:00.02 |     640 |     0 |      0 |       |       |          |         |
|   4 |    TABLE ACCESS FULL     | T_ORD      |      1 |    100K|    100K|00:00:00.02 |     896 |     0 |      0 |       |       |          |         |
---------------------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("S"."ORD_SEQ"="O"."ORD_SEQ")
       filter(("S"."STLM_AMT"<>"O"."ORD_AMT" OR "S"."CUS_ID"<>"O"."CUS_ID"))

문제 ​

  1. 2번 줄의 Used-Mem 괄호 안 숫자와 Used-Tmp, Reads/Writes가 무엇을 뜻하는지 설명하시오. sqlplus에서는 빠른데 배치에서만 느린 원인도 찾으시오.
  2. 배치를 고치고, 2013년의 그 두 줄이 지금은 왜 필요 없는지와 온라인을 지키려면 대신 무엇을 볼지 서술하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자