Skip to content
튜닝 연습인덱스 사용 조건
IDX-034

5분마다 도는 판매 변경분 연계가 바뀐 판매 몇 건을 보내려고 판매 테이블을 다 읽는다

중급INSERT유통34 / 700

상황 ​

유통 본사는 판매가 등록되거나 고쳐지면 5분 안에 정보계로 보낸다. 연계 솔루션이 5분마다 아래 INSERT를 돌려 변경분을 연계 테이블에 담고, 다 보낸 뒤 제어 테이블의 마지막 연계 시각을 고친다. 변경분은 한 번에 몇 건뿐인데 이 INSERT가 연계 시간의 대부분을 차지한다. 지난달 DBA가 MOD_DTT에 인덱스를 만들었지만 계획은 그대로다. 개발사는 "SQL에 함수도 형변환도 없다"라고 한다.

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록(전체 스캔 4,511) · MOD_DTT DATE(수정 일시) · 5분 동안 바뀌는 판매는 보통 2 ~ 10건 (문제 설정: 교재의 CF10은 적재 때 MOD_DTT가 한꺼번에 찍혔다. 여기서는 판매를 등록하거나 고칠 때마다 시각이 찍히는 운영 테이블이라고 본다)
  • 인덱스 IX_CF10_MOD (MOD_DTT): 지난달 생성 · BLEVEL 2 · 리프 약 1,330블록 · 판매가 바뀐 순서와 행이 놓인 순서가 비슷해 CF가 좋다 · 통계 최신
  • IF_CTL 연계 제어(연계 솔루션이 만든 테이블): IF_ID VARCHAR2(10) PK · LAST_TS TIMESTAMP(0) (마지막으로 보낸 시각, 소수 초 없음) · 연계마다 한 행
  • IF_SLE_OUT 연계 테이블: 보낼 판매를 담고, 보낸 뒤 비운다

원본 SQL ​

sql
INSERT INTO IF_SLE_OUT (SLE_NO, SLE_DT, SHP_NO, MOD_DTT)
SELECT a.SLE_NO, a.SLE_DT, a.SHP_NO, a.MOD_DTT
  FROM CF10 a
 WHERE a.MOD_DTT > (SELECT c.LAST_TS FROM IF_CTL c WHERE c.IF_ID = 'SLE')

실행계획 학습용 예시 ​

xplan
---------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name       | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT              |            |      1 |        |      0 |00:00:00.07 |    4528 |
|   1 |  LOAD TABLE CONVENTIONAL      | IF_SLE_OUT |      1 |        |      0 |00:00:00.07 |    4528 |
|*  2 |   TABLE ACCESS FULL           | CF10       |      1 |  25000 |      6 |00:00:00.07 |    4513 |
|   3 |    TABLE ACCESS BY INDEX ROWID| IF_CTL     |      1 |      1 |      1 |00:00:00.01 |       2 |
|*  4 |     INDEX UNIQUE SCAN         | IF_CTL_PK  |      1 |      1 |      1 |00:00:00.01 |       1 |
---------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(INTERNAL_FUNCTION("A"."MOD_DTT")> (SELECT "C"."LAST_TS" FROM "IF_CTL" "C" WHERE "C"."IF_ID"='SLE'))
   4 - access("C"."IF_ID"='SLE')

문제 ​

  1. SQL에 함수가 없는데도 2번 줄에 INTERNAL_FUNCTION이 붙은 이유를 테이블 정의로 설명하시오.
  2. IX_CF10_MOD로 변경분만 찾아가도록 SQL을 고치고, 고친 SQL이 원본과 같은 판매를 고르는지 소수 초 관점에서 따져 설명하시오.
  3. 연계 솔루션 쪽에서 할 수 있는 근본 대책을 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자