테마
05화 · 실습과 기록
여기서 하는 일: 95%를 지우고, 안 줄어드는 걸 확인한 뒤, 고수위선을 직접 내린다.
1_사건.md를 읽은 것은 "선배가 하는 걸 지켜본 것"이고, 이 문서를 끝내야 직접 해 본 것이 된다. 개념이 막히면2_파고들기.md를 펼친다.시간이 없는 주에는 STEP 0 → 1 → 2 → 6만 한다(약 40분).
STEP 0 — 기반화에서 처음 하는 일 (3분)
조각 개선화는 직전 리비전의 diff를 뜨는 일로 시작한다. 05화는 기반화라서 고칠 조각이 없다. 대신 아래 내용을 먼저 적는다.
이 화가 다음에 청구서를 보낼 화 : 14화 「야간 배치가 아침을 넘긴다」
보낼 것 :
① 보관을 DELETE 로만 하는 정책이 만드는 고수위선 빚
② 매달 반복되는 SHRINK/MOVE 의 비용
③ 02화에서 만든 인덱스 2개(48MB)의 적재 비용bash
docker start ora-hanordersql
-- 전제 확인 (02화 종료 상태)
SELECT table_name, num_rows, blocks FROM user_tables WHERE table_name='T_ORD_BIG';
-- 기대: 1,000,000 / 5,923
SELECT index_name FROM user_indexes WHERE table_name='T_ORD_BIG';
-- 기대: IX_ORD_BIG_DT, IX_ORD_BIG_DT_AMT
blocks가 5,923이 아니면 통계를 다시 수집한다.EXEC DBMS_STATS.GATHER_TABLE_STATS(USER,'T_ORD_BIG',method_opt=>'FOR ALL COLUMNS SIZE 1',cascade=>TRUE,no_invalidate=>FALSE);
STEP 1 — 예측을 봉인한다 (3분)
50만 행짜리 로그 테이블이 있다. 전체 스캔 Buffers 는 3,602 다.
여기서 95%(475,025행)를 DELETE 하고 통계를 다시 모을 것이다.
Q1. DELETE 후 같은 조회의 Buffers 는 얼마가 될 것 같은가? ______
Q2. 틀렸다면, 왜 그렇게 되는가?
________________________________________________________
Q3. VARCHAR2(4000) 컬럼 3개짜리 테이블과, 같은 값을 담은
VARCHAR2(2)/(30)/(100) 테이블의 블록 수 비는? ______ : ______
Q4. 행을 72바이트로 넣고 나중에 270바이트로 UPDATE 하면,
전체 스캔은 몇 배 느려질 것 같은가? ______
인덱스 경유는? ______▶ 적고 나서 펼치기
- Q1: 대부분 "20분의 1"이나 "크게 준다"라고 쓴다. 실측값은 3,602. 한 블록도 줄지 않는다.
- Q3: 대부분 "4000 쪽이 훨씬 크다"라고 쓴다. 실측값은 874 : 874로 똑같다.
- Q4: 전체 스캔은 1.13배(3,904 vs 3,469)밖에 늘지 않는다. 인덱스 경유는 41.6배(30,549 vs 735)로 터진다.
이 화는 네 번 틀리도록 짜여 있다. 01화나 02화와 달리 오늘은 "고치는" 화가 아니라 "왜 이렇게 됐는지 알아내는" 화다.
STEP 2 — 고수위선 사건 (10분) ★ 오늘의 본체
bash
cd 10_본편_튜너의_1년/05화_블록이라는_그릇/실습
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 00_고수위선.sqlpowershell
Set-Location 10_본편_튜너의_1년\05화_블록이라는_그릇\실습
Get-Content 00_고수위선.sql -Encoding UTF8 | docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1스크립트는 맨 앞에서 실습 테이블을 지우고 시작한다. 그래서 몇 번을 돌려도 결과가 같다.
⚠️ 왜 초기화가 필요한가 — 실측으로 걸린 함정
[G]에서SHRINK SPACE를 한 뒤 스크립트를 다시 돌리면[B]가 3,602가 아니라 183에서 시작한다. "지웠는데 안 줄어든다"는 이 화의 핵심 장면이 통째로 사라진다. 고수위선이 올라간 상태에서 출발해야 이 이야기가 성립한다.
아홉 단계에서 확인할 것
| 단계 | 무엇 | 기대 | ☐ |
|---|---|---|---|
| [A] | 50만 행 적재 | 세그먼트 3,712블록 · 익스텐트 44 · HWM 아래 3,665 | ☐ |
| [B] | 전체 스캔 | TABLE ACCESS FULL · 3,602 · A-Rows 100,000 | ☐ |
| [C] | 95% DELETE | 남은 행 24,975 · 세그먼트·익스텐트·HWM 전부 그대로 | ☐ |
| [D] | ★ 같은 전체 스캔 | 3,602. A-Rows만 4,995로 줄었다 | ☐ |
| [E] | SPACE_USAGE | FULL 0 · FS4 3,123 | ☐ |
| [F] | SHRINK SPACE COMPACT | FULL 0→179로 모였는데 여전히 3,602 | ☐ |
| [G] | SHRINK SPACE | HWM 180 · 익스텐트 44→17 · 183 | ☐ |
| [H] | ALTER TABLE MOVE | HWM 192 · 183 | ☐ |
| [I] | TRUNCATE | 세그먼트 8블록 · 익스텐트 1 · 1 | ☐ |
각 단계에서 눈으로 짚을 것
[C][D] — 세 숫자를 나란히 보라
USER_SEGMENTS.blocks 3712 -> 3712 받아 놓은 공간: 그대로
USER_TABLES.blocks 3665 -> 3665 고수위선: 그대로
Buffers 3602 -> 3602 읽는 양: 그대로
NUM_ROWS 500000 -> 24975 행만 줄었다
☐ "읽는 양은 행수가 아니라 고수위선이 정한다" 를 이 네 줄로 말할 수 있는가?
[E] — FULL 이 0 이라는 것
☐ 3,123개 블록이 75% 이상 비었는데도 왜 전부 읽히는가?
-> 블록을 열어 봐야 비었는지 안다. 안 열면 모른다
[F] — 모으는 것과 선을 내리는 것은 다른 일이다
FULL 0 -> 179 (행이 앞쪽 179 블록에 모였다)
blocks 3665 -> 3665 (선은 그대로)
Buffers 3602 -> 3602
☐ 왜 이 둘을 분리해 놨는지 설명할 수 있는가? (힌트: 잠금 시간)
[G] — 익스텐트까지 반납된다
☐ 44 -> 17 로 줄어든 것을 확인. SHRINK 는 공간도 돌려준다STEP 1의 예측을 꺼낸다
| Q1을 맞혔나? | |
"COMPACT로는 안 내려간다"를 예상했나? | |
TRUNCATE가 1블록이 되는 것을 예상했나? |
STEP 3 — 주소를 분해한다 (10분)
bash
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 01_ROWID와_4계층.sqlpowershell
Get-Content 01_ROWID와_4계층.sql -Encoding UTF8 | docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1읽기 전용 스크립트다. 아무것도 바꾸지 않는다.
채점표 — 돌리기 전에 먼저 답해 보자
| # | 질문 | 내 답 | 실측 |
|---|---|---|---|
| ① | T_ORD_BIG 세그먼트가 받은 블록은? | 6,016 | |
| ② | 고수위선 아래 블록은? | 5,923 | |
| ③ | 전체 스캔이 읽는 블록은? | 5,826 | |
| ④ | 행이 실제로 들어 있는 블록은? | 5,813 | |
| ⑤ | 익스텐트 62개는 전부 같은 크기인가? | 아니다. 64KB 16개 + 1MB 46개 | |
| ⑥ | ROWID 네 조각 중 테이블스페이스는 몇 번째? | 없다 | |
| ⑦ | 상대 파일번호 1024를 쓰는 테이블스페이스는 몇 개? | 3개 (SYSTEM·SYSAUX·UNDOTBS1) | |
| ⑧ | 01화의 "블록당 169건"을 ROWID로 다시 세면? | 172 |
📌 ④와 ②의 차이를 꼭 설명하고 넘어가자
5,923 − 5,813 = 110. 고수위선 아래인데 행이 하나도 없는 블록이 110개다. 저 110개는 매번 읽힌다.
T_ORD_BIG에도 이미 작은 빚이 있다.
⑦이 왜 결정적인가
sql
-- 이 함수의 인자 개수를 보라
DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO(row_id, schema_name, object_name)ROWID만으로 절대 파일 번호를 구할 수 있었다면 인자가 하나면 됐다. 오라클이 만든 API가 소유자와 객체명을 요구하는 것 자체가 "그 정보는 ROWID 안에 없다"는 증거다.
STEP 4 — 행 이전을 만든다 (15분)
bash
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 02_행이전과_행연결.sqlpowershell
Get-Content 02_행이전과_행연결.sql -Encoding UTF8 | docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1⚠️
UPDATE가 네 번 들어 있어 약 1분 걸린다.
채점표 — PCTFREE만 다른 다섯 테이블
모두 10만 행이고 최종 데이터는 전부 같다. 만드는 방법만 다르다.
| 만든 방식 | UPDATE 전 블록 | 이전행 | 이전율 | 인덱스 경유 Buffers | ☐ |
|---|---|---|---|---|---|
PCTFREE 0 + 나중에 UPDATE | 1,000 | 76,169 | 76.2% | 30,549 | ☐ |
PCTFREE 10 + 나중에 UPDATE | 1,126 | 73,494 | 73.5% | 29,482 | ☐ |
PCTFREE 40 + 나중에 UPDATE | 1,630 | 56,984 | 57.0% | 23,083 | ☐ |
PCTFREE 75 + 나중에 UPDATE | 3,772 | 0 | 0% | 786 | ☐ |
| 처음부터 최종 길이로 적재 | 3,520 | 0 | 0% | 735 | ☐ |
눈으로 짚을 것
D *(공개 사이트에는 없음)* 전체 스캔 비교 — 3,904 vs 3,469
☐ 7만 6천 행이 이사를 갔는데 왜 1.13배밖에 안 되는가?
-> 전체 스캔은 어차피 전부 읽는다. 쪽지를 따라갈 필요가 없다
D *(공개 사이트에는 없음)* 인덱스 경유 비교 — 30,549 vs 735
☐ INDEX RANGE SCAN 줄은 양쪽 다 45 인 것을 확인
☐ 차이가 전부 TABLE ACCESS BY INDEX ROWID 에서 난다는 것을 확인
☐ "행 이전은 인덱스 경유에서만 드러난다" 를 숫자로 말할 수 있는가?
D *(공개 사이트에는 없음)* table fetch continued row — 15,252 vs 0
☐ 2만 건 조회에 15,252번을 더 걸었다. 이름이 뜻 그대로다
[E] MOVE 후 — chain_cnt 0 인데 Buffers 가 735 가 아니다
☐ CLUSTERING_FACTOR 약 52,200 vs 3,449 를 확인 (이 둘만 실행 환경에 따라 조금 흔들린다)
☐ "MOVE 는 모양을 고치지 순서를 안 고친다" 를 설명할 수 있는가?
[F] 행 연결 — COUNT(C1) 15,207 vs COUNT(C3) 25,207
☐ 첫 컬럼만 읽으면 continued row 가 0 인 것을 확인
☐ 그래서 "자주 읽는 컬럼을 앞에" 라는 규칙이 나온다☠️ 여기서 교과서가 뭉뚱그리는 지점
"행 이전"과 "행 연결"은 둘 다 CHAIN_CNT 컬럼 하나에 잡히지만 다른 현상이다.
| 행 이전 | 행 연결 | |
|---|---|---|
| 원인 | 블록에 자리가 없다 | 행이 블록보다 크다 |
PCTFREE로 막히나 | 막힌다 (문턱만 넘으면) | 안 막힌다 |
MOVE로 고쳐지나 | 고쳐진다 (CF는 못 돌려받는다) | 안 고쳐진다 |
자세한 내용은 2_파고들기 §6에 있다.
STEP 5 — VARCHAR2(4000)을 재판한다 (10분)
bash
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 03_VARCHAR2_4000.sqlpowershell
Get-Content 03_VARCHAR2_4000.sql -Encoding UTF8 | docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1먼저 유죄 판결문을 써 보자
"VARCHAR2(4000) 은 나쁘다. 왜냐하면 ______________________________ 때문이다."▶ 돌린 뒤에 펼치기
대부분 "공간을 낭비하니까"라고 쓴다. 실측 결과는 다르다.
| 무엇을 재나 | VARCHAR2(4000) | 알맞게 선언 |
|---|---|---|
| 블록 | 874 | 874 |
AVG_ROW_LEN | 23 | 23 |
전체 스캔 Buffers | 821 | 821 |
공간은 한 바이트도 더 안 쓴다. VARCHAR2는 가변 길이다.
진짜 죄목은 세 가지다.
- 통계가 없으면 선언 길이가 그대로 비용이 된다. 정렬
Cost가 59,755 vs 1,401(42.7배),E-Bytes가 272M vs 4,810K로 갈린다. 실제로 읽은Buffers는 822로 똑같다. 틀린 건 속도가 아니라 오라클의 눈이다. - 인덱스 키 길이를 잡아먹는다.
(VARCHAR2(4000), VARCHAR2(4000))인덱스에 긴 값을 넣으면ORA-01450: maximum key length (6397) exceeded에러가 난다. 느려지는 정도가 아니라 적재가 죽는다. - 언젠가 누군가 그 4000자를 채운다. 그 순간 STEP 4의 행 이전과 행 연결이 시작된다.
STEP 6 — T1 리포트 3호 ★ 오늘의 산출물
양식은 T1_단건SQL_튜닝리포트.md를 따른다.
이번 호는 성격이 다르다. SQL은 한 글자도 고치지 않았다. 고친 것은 저장 구조와 보관 정책이다. 그래서 「조치」 칸에는 SQL 리비전 대신 DDL과 정책이 들어간다.
┌──────────────────────────────────────────────────────────────────┐
│ T1 단건 SQL 튜닝 리포트 — 3호 │
├──────────────────────────────────────────────────────────────────┤
│ 대상 : T_ORD_LOG 주문상태이력 조회 (정산 현업 조민우) │
│ 측정 일시 : ____________ 측정 조건 : 단독 세션 · 1회 실행 │
│ 리비전 : (없음 — SQL 미변경. 저장 구조 변경) │
├──────────────────────────────────────────────────────────────────┤
│ 1. 현상 │
│ 이력 95%(475,025행) 삭제 후에도 조회 Buffers 3,602 → 3,602 │
│ 2. 원인 │
│ ______________________________________________________________ │
│ 3. 조치 │
│ 즉시 : ______________________________________________________ │
│ 근본 : ______________________________________________________ │
│ 4. 효과 (Buffers 로) │
│ ______________________________________________________________ │
│ 5. 리스크 ★ 비우면 반려된다 │
│ ______________________________________________________________ │
│ 6. 회귀 검증 │
│ ______________________________________________________________ │
└──────────────────────────────────────────────────────────────────┘2번 「원인」에 들어가야 할 것
DELETE는 행을 지울 뿐 고수위선을 내리지 않는다- 전체 스캔은 고수위선까지 읽는다(
FULL블록이 0개,FS4가 3,123개인데도 전부 읽힌다) USER_SEGMENTS.blocks3,712와USER_TABLES.blocks3,665 모두DELETE전후가 같다
3번 「조치」 — 즉시와 근본을 나눠 쓴다
| 쓸 것 | |
|---|---|
| 즉시 | ENABLE ROW MOVEMENT + SHRINK SPACE. 야간 수행. Buffers 3,602 → 183 |
| 근본 | 보관을 DELETE로만 하는 정책 자체를 바꾼다: 파티션 또는 아카이브 테이블 + TRUNCATE |
LOG_ST VARCHAR2(4000)에 코드와 설명을 같이 담는 설계를 분리한다(행 이전의 원인) |
5번 「리스크」에 반드시 들어가야 할 것
이번 호는 리스크 칸이 본문보다 중요하다. 이 칸이 14화로 가는 청구서다.
SHRINK/MOVE는 행을 전부 다시 쓴다. redo가 생기고, 마지막 순간에 테이블 전체를 잠근다. 월말 배치 창에 끼워 넣어야 한다- 다음 달에 또 같은 일이 생긴다.
DELETE보관 정책이 그대로인 한 이 작업은 치료가 아니라 매달 반복되는 청소다 MOVE를 쓰면 인덱스가UNUSABLE상태가 된다.REBUILD를 빠뜨리면ORA-01502장애가 난다ENABLE ROW MOVEMENT는ROWID가 바뀌어도 좋다는 허락이다.ROWID를 저장해 쓰는 코드가 있으면 깨진다- 02화에서 만든 인덱스 2개가 48MB다(
IX_ORD_BIG_DT22MB +IX_ORD_BIG_DT_AMT26MB). 테이블(47MB)보다 크다. 적재할 때마다 같이 갱신된다 → 14화 T_ORD_BIG에도 고수위선 아래 빈 블록 110개(5,923 − 5,813)가 이미 있다
6번 「회귀 검증」
| 확인할 것 | 방법 |
|---|---|
SHRINK 후 행수가 그대로인가 | SELECT COUNT(*) 전후 비교 (24,975) |
| 결과가 같은가 | 조치 전후 COUNT(*), MAX(LOG_DT) 비교 |
MOVE를 썼다면 인덱스가 살아 있나 | SELECT status FROM user_indexes로 VALID인지 확인 |
ROWID를 쓰는 코드가 있나 | 애플리케이션 검색. 있으면 SHRINK 금지 |
STEP 7 — 블록을 열어 본다 (선택 · 10분)
SYSDBA 권한이 필요하다. 시간이 없으면 건너뛰어도 된다. 운영 DB에서는 함부로 하면 안 된다. 트레이스 파일이 쌓이고, DBA 승인을 받아야 하는 작업이다. 전제: STEP 4를 먼저 돌려야 한다(
T_MIG10과CHAINED_ROWS가 있어야 한다).
bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 90_블록덤프_SYSDBA.sqlpowershell
Get-Content 90_블록덤프_SYSDBA.sql -Encoding UTF8 | docker exec -i ora-hanorder sqlplus -s "/ as sysdba"Git Bash에서
MSYS_NO_PATHCONV=1을 빼면/를 경로로 바꿔 버려서 접속이 안 된다.
스크립트를 돌리면 트레이스 파일 경로가 나온다. 그 파일에서 네 군데만 본다.
| 보는 곳 | 실측 예 | 뜻 |
|---|---|---|
itc: 2 | 2 | ITL 슬롯 수. 이 블록을 동시에 고칠 수 있는 트랜잭션 수 |
0x02 ... --U- 100 | --U- / Lck 100 | 커밋됐지만 정리 전 · 행 100개를 잠갔던 기록 |
nrow=100 · avsp=0x2 | 행 디렉터리 항목 수 · 남은 빈 공간 2바이트 | |
tl: 9 fb: --H----- + nrid: | ★ 이사 간 행. 9바이트 쪽지 하나만 남았다 | |
tl: 268 fb: --H-FL-- | 멀쩡한 행. 머리(H)·첫조각(F)·끝조각(L) 다 있음 |
bash
# 뽑아 보기
docker exec -i ora-hanorder sh -c "grep -nE 'itc:|^Itl|^0x0[12] |nrow=|avsp=|^tl: |^nrid:' <경로>"☐
ROWID는 머리를 가리킨다. 몸이 이사를 가도ROWID는 바뀌지 않는다. 그래서 인덱스를 고칠 필요가 없고, 그래서 조회가 두 번 간다. STEP 4의 30,549는 이 한 문장으로 설명된다.
STEP 8 — 서술 답안 (400~600자)
조민우 씨에게 보낼 회신을 쓴다. 아침에 "확인해 보고 연락드리겠습니다"라고 했으니 답을 줘야 한다.
4단계 프레임(현상/진단 → 원인 → 개선안 → 근거/효과)은 01화 3_실습과_기록.md와 같다.
▶ 선배의 첨삭 포인트 (쓰고 나서)
① "데이터를 지워도 안 빨라집니다"로 끝내면 반쪽이다. 현업이 묻는 것은 왜가 아니라 그래서 언제 빨라지나다. 조치와 일정을 같이 적는다.
② 현업이 알아듣는 말로 쓴다. "고수위선이 안 내려갔습니다"로는 뜻이 전달되지 않는다. "창고 선반에서 서류만 버리고 상자는 그대로 둔 상태라, 점검하는 사람은 여전히 모든 상자를 열어 봅니다"라고 옮겨야 한다.
③ 근본 원인을 숨기지 않는다. 이번 달에 SHRINK로 183을 만들어도 다음 달에 또 똑같아진다. 그 사실을 적지 않으면 다음 달에 똑같은 전화를 받게 되고, 그때는 그 책임을 떠안게 된다.
④ 숫자는 Buffers로 쓴다. "20배 빨라졌습니다"가 아니라 "조회 한 번에 읽는 블록이 3,602에서 183으로 줄었습니다"라고 쓴다. 여기에 "행을 95% 지운 것만으로는 3,602에서 3,602로, 전혀 줄지 않았습니다"를 같이 적어야 조치의 가치가 드러난다.
STEP 9 — 파인만 자가설명
절차는 01화와 같다. 1단 백지 설명 → 2단 막힘 태그(최소 1개) → 3단 원천 복귀 → 4단 재설명 순서로 진행한다.
오늘 자주 나오는 태그 세 가지
| 태그 | 전형적인 문장 |
|---|---|
#인과 | "왜 DELETE가 고수위선을 안 내리는지 설명하다 막혔다" → §3 |
#용어 | "행 이전과 행 연결의 차이를 말로 못 하겠다" → §6 |
#수치 | "전체 스캔은 1.13배인데 인덱스 경유는 41.6배인 이유를 못 세겠다" → §6의 두 실행계획을 나란히 놓고 45블록 줄을 찾아본다 |
4단 되묻기 3문 (오늘 버전)
- 조건 반전: "고수위선이 성능에 도움이 되는 경우가 있나?" (힌트: 멀티블록 읽기와
INSERT경로) - 반례 요구: "
SHRINK SPACE를 하면 안 되는 테이블을 하나 든다면?" - 측정 지목: "'이 테이블에 행 이전이 있다'를 증명하려면 무엇을 재야 하나? 두 가지를 꼽아 보자."
태그는 _막힘로그.md로 옮긴다.
완료 체크리스트
- [ ] STEP 0: 이 화가 14화로 보낼 청구서 세 줄을 먼저 적었다
- [ ] STEP 1: 보기 전에 예측 4개를 적었다
- [ ] STEP 2: [A]~[I]를 돌리고 3,602 → 3,602 → 183 → 1을 확인했다
- [ ] STEP 2:
COMPACT가FULL을 179로 만들고도Buffers는 바꾸지 못하는 것을 눈으로 짚었다 - [ ] STEP 3: 6,016 / 5,923 / 5,826 / 5,813 네 숫자의 차이를 각각 설명했다
- [ ] STEP 3:
ROWID네 조각에 테이블스페이스가 없다는 것을 세 가지 증거로 말할 수 있다 - [ ] STEP 4: 735 vs 30,549를 확인하고,
INDEX RANGE SCAN줄이 양쪽 다 45인 것을 짚었다 - [ ] STEP 4:
MOVE후에도 735가 아닌 이유(CF약 52,200)를 적었다 - [ ] STEP 5:
VARCHAR2(4000)의 진짜 죄목 세 가지를 적었다 - [ ] STEP 6: T1 리포트 3호를 썼고, 리스크 칸에 14화 청구서를 명시했다
- [ ] STEP 8: 조민우 씨 회신을 문장으로 풀어 썼다("다음 달에 또 그렇게 된다"를 포함했는가)
- [ ] STEP 9: 막힘 태그를 최소 1개
_막힘로그.md에 옮겼다
완결성 게이트: STEP 6의 리스크 칸과 STEP 9의 태그가 비어 있으면 이 화는 미완성이다.
실습 뒷정리
이 화의 실습 테이블은 다음 화에 필요 없다. 다 쓴 뒤 지워도 된다. 각 스크립트가 맨 앞에서 알아서 지우므로 꼭 할 필요는 없다.
sql
BEGIN
FOR i IN (SELECT table_name FROM user_tables
WHERE table_name IN ('T_ORD_LOG','T_MIG00','T_MIG10','T_MIG40','T_MIG75',
'T_MIG_OK','T_CHAIN','T_W4000','T_W30','CHAINED_ROWS')) LOOP
EXECUTE IMMEDIATE 'DROP TABLE '||i.table_name||' PURGE';
END LOOP;
END;
/⚠️
T_ORD_BIG,T_ORD,T_ORD_DET와 인덱스 2개는 절대 건드리면 안 된다. 다음 화에서 그대로 쓴다.
다음 화로 넘기는 상태
| 무엇 | 값 |
|---|---|
T_ORD_BIG | 변경 없음. 100만 행 · 인덱스 2개 · HWM 아래 5,923블록 |
| 새로 만든 빚 | 보관을 DELETE로만 하는 정책: 매달 고수위선이 다시 올라간다 |
| 기록해 둔 수치 | 3,602 → 3,602 → 183 · 인덱스 2개 48MB · 빈 블록 110개 |
| 다시 확인한 것 | MOVE로도 돌아오지 않는 CF. 04화에서 본 원리 그대로다(ORDER BY로 다시 쌓아야 고쳐진다) |
| 열어 둔 질문 | ITL 슬롯이 모자라면 → 12화 · 13화 |
다음 → 06화 「100만 번의 왕복」: 오늘은 한 테이블 안에서 블록을 몇 개 읽는지를 봤다. 다음 화에서는 두 테이블 사이를 몇 번 왕복하는지를 본다.