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

배치 서버를 옮기는 리허설에서 1년 지난 주문만 지우던 배치가 주문 100만 건을 다 지웠다

중급DELETE버거29 / 700

상황 ​

버거원 본사는 월말마다 1년이 지난 주문을 정보계로 넘긴 뒤 운영 DB에서 지운다. 배치 서버를 새 장비로 옮기면서 복제 DB에서 리허설을 했는데, 삭제 단계가 주문 1,000,000건을 지웠다고 찍혔다. 예전 서버에서 같은 기준일로 돌리면 약 50만 건이다. 배치 코드는 한 줄도 바꾸지 않았다. 바뀐 것은 서버의 언어 설정이다. 예전 서버의 배치 계정에는 NLS_DATE_FORMAT=YYYYMMDD가 환경 변수로 걸려 있었고, 새 서버에는 NLS_LANG=AMERICAN_AMERICA.AL32UTF8만 걸려 있어 NLS_DATE_FORMAT이 기본값 DD-MON-RR이다.

테이블과 인덱스 ​

  • ORD 주문: 1,000,000행 · 22,422블록 · ORD_DT VARCHAR2(8) ('20120101' ~ '20131231', 731일 · 하루 약 1,368건)
  • 인덱스 ORD_PK (ORD_NO) · ORD_X01 (ORD_DT, ORD_HMS) · 통계 최신
  • 배치는 기준일 :p_base_dt(DATE)를 받는다. 이번 리허설의 기준일은 2013-12-31이다

원본 SQL ​

sql
-- 기준일로부터 1년 이전의 주문을 지운다 (정보계 이관은 앞 단계에서 끝났다)
DELETE FROM ORD
 WHERE ORD_DT < TO_CHAR(ADD_MONTHS(:p_base_dt, -12))

실행계획 학습용 예시 ​

xplan
[예전 서버 · NLS_DATE_FORMAT = YYYYMMDD]
TO_CHAR(ADD_MONTHS(DATE '2013-12-31', -12))  →  '20121231'
삭제 499,320건 (2012-01-01 ~ 2012-12-30)

[새 서버 · NLS_DATE_FORMAT = DD-MON-RR]
TO_CHAR(ADD_MONTHS(DATE '2013-12-31', -12))  →  '31-DEC-12'
-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   0 | DELETE STATEMENT   |      |      1 |        |      0 |00:00:38.70 |    3155K|
|   1 |  DELETE            | ORD  |      1 |        |      0 |00:00:38.70 |    3155K|
|*  2 |   TABLE ACCESS FULL| ORD  |      1 |   1000K|   1000K|00:00:00.61 |   22426 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("ORD_DT"<TO_CHAR(ADD_MONTHS(:P_BASE_DT,-12)))

문제 ​

  1. 새 서버에서 TO_CHAR(ADD_MONTHS(:p_base_dt, -12))가 만든 문자열이 무엇이고, 그 문자열과 ORD_DT를 비교한 결과가 왜 100만 건이 됐는지 설명하시오.
  2. 기준일이 2013-11-15였다면 새 서버에서 몇 건이 지워졌을지 따져 보고, 이 배치가 어느 서버에서든 같은 결과를 내도록 고치시오.
  3. 이런 사고를 운영 전에 막는 장치를 제안하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자