Skip to content
튜닝 연습파싱과 바인드 변수
PARSE-034

DW로 넘기는 판매상품 파일 두 개, ARRAYSIZE를 올리자 한쪽만 논리 읽기가 줄었다

기초SELECT유통579 / 700

상황 ​

유통 본사의 야간 스크립트는 SQL*Plus로 판매상품(CF11)을 파일 두 개로 내려 DW에 넘긴다. [E1]은 테이블 순서 그대로, [E2]는 DW 요청대로 상품번호 순으로 정렬한 파일이다. 둘 다 40초 안팎이 걸린다. DBA가 스크립트 맨 위에 SET ARRAYSIZE 1000 한 줄을 넣어 시험해 보니 둘 다 빨라졌다. 그런데 [E1]은 논리 읽기가 9분의 1로 줄었고 [E2]는 한 블록도 줄지 않았다. 조민우가 물었다. "같은 테이블을 같은 크기로 받았는데 왜 한쪽만 줄어요?"

테이블과 인덱스 ​

  • CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · 통계 최신
  • 스크립트는 배치 서버에서 돌고 DB 서버와의 왕복은 0.4ms다. 지금은 ARRAYSIZE를 정하지 않았다(SQL*Plus 기본값 15).
  • [E2]의 정렬은 메모리 안에서 끝난다(work area가 충분하다).

원본 SQL ​

sql
-- dw_cf11.sql (2014) : 배치 서버에서 sqlplus -s pup/***@DIST @dw_cf11.sql
SET HEADING OFF FEEDBACK OFF PAGESIZE 0 LINESIZE 200 TRIMSPOOL ON TERMOUT OFF

SPOOL /dw/in/cf11_all.dat
-- [E1] 판매상품 전체 (순서 상관없음)
SELECT SLE_NO || '|' || ITM_NO || '|' || SLE_QTY || '|' || SLE_UPRC
  FROM CF11;
SPOOL OFF

SPOOL /dw/in/cf11_by_item.dat
-- [E2] 상품번호 순 (DW 적재 순서)
SELECT ITM_NO || '|' || SLE_NO || '|' || SLE_QTY || '|' || SLE_UPRC
  FROM CF11
 ORDER BY ITM_NO, SLE_NO;
SPOOL OFF
EXIT

실행계획 학습용 예시 · 정렬 유무에 따른 차이는 교재 09화 실측과 같은 모양 ​

xplan
[지금 · ARRAYSIZE 15 (기본값) · 세션 통계 증가분]
          경과      SQL*Net roundtrips   consistent gets   sorts (memory)
  [E1]    38.2 초        73,117              81,329               0
  [E2]    41.6 초        73,117               8,207               1

[DBA 시험 · SET ARRAYSIZE 1000]
  [E1]     4.1 초         1,100               9,309               0
  [E2]     7.3 초         1,100               8,207               1

[E1 계획 · ARRAYSIZE 15]
------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |   1096K|00:00:01.02 |   81312 |
|   1 |  TABLE ACCESS FULL| CF11 |      1 |   1096K|   1096K|00:00:01.02 |   81312 |
------------------------------------------------------------------------------------

[E2 계획 · ARRAYSIZE 15 (1000일 때도 Buffers는 같다)]
-----------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Used-Mem |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |   1096K|00:00:03.12 |    8204 |          |
|   1 |  SORT ORDER BY     |      |      1 |   1096K|   1096K|00:00:03.12 |    8204 |   46M (0)|
|   2 |   TABLE ACCESS FULL| CF11 |      1 |   1096K|   1096K|00:00:00.21 |    8204 |          |
-----------------------------------------------------------------------------------------------

문제 ​

  1. [E1]과 [E2]의 왕복 수가 둘 다 73,117인 이유와, ARRAYSIZE를 올렸을 때 [E1]만 consistent gets가 준 이유를 위 숫자로 설명하시오.
  2. 스크립트를 고치시오. [E2]의 consistent gets를 더 줄일 방법이 있는지도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자