Skip to content
튜닝 연습파티션
PART-016

파티션으로 옮긴 뒤 반품 영수증 조회가 논리 읽기 상위 목록에 올라왔다

기초SELECT유통391 / 700

상황 ​

유통 매장 POS의 「반품·교환」 화면은 영수증 바코드(판매번호 SLE_NO)를 찍어 원래 판매를 찾는다. 다섯 매장에서 하루 약 3,000번 호출된다. 지난달 CF10을 월별 파티션 CF10_P로 옮긴 뒤 이 SQL이 AWR의 논리 읽기 상위 목록에 올라왔다. 바코드에는 판매번호만 있고, POS는 판매번호 말고는 아무것도 넘기지 않는다. POS 프로그램은 이번 분기에 고칠 수 없다.

테이블과 인덱스 ​

  • CF10_P 판매(파티션 복사본, 문제 설정): CF10 500,000행을 PARTITION BY RANGE (SLE_DT) 월별 24칸(P202201 ~ P202312)과 빈 PMAX로 나눠 CTAS로 지었다. 칸 하나는 약 20,800행이고 FULL로 약 191블록이다. 빈 PMAX는 세그먼트가 없다. P202311은 23번째 칸이다.
  • SLE_NO VARCHAR2(15)는 판매일자 8자리 + - + 그날의 일련번호 4자리다('20231107-0215'). 적재 프로그램이 SLE_DT로 번호를 만들기 때문에 앞 8자리는 지금까지 언제나 그 행의 SLE_DT와 같았다. 이 규칙을 지키는 제약은 없다.
  • PK CF10_P_PK (SLE_NO, SLE_DT)는 LOCAL이다(PK를 LOCAL로 만들려고 파티션 키를 뒤에 붙였다). 칸마다 높이 2다. 다른 인덱스는 없고 통계는 최신이다.
  • 옮기기 전 CF10에서는 CF10_PK (SLE_NO)로 4블록을 읽었다.

원본 SQL ​

sql
SELECT SLE_NO, SLE_DT, SLE_HMS, SHP_NO
  FROM CF10_P
 WHERE SLE_NO = :sle_no

실행계획 학습용 예시 · 칸 크기는 CF10을 24칸으로 나눈 값 ​

xplan
[:sle_no = '20231107-0215']
-----------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name      | Starts | E-Rows | A-Rows |      A-Time | Buffers | Pstart | Pstop |
-----------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |           |      1 |        |      1 | 00:00:00.01 |      49 |        |       |
|   1 |  PARTITION RANGE ALL                |           |      1 |      1 |      1 | 00:00:00.01 |      49 |      1 |    25 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID | CF10_P    |     24 |      1 |      1 | 00:00:00.01 |      49 |      1 |    25 |
|*  3 |    INDEX RANGE SCAN                 | CF10_P_PK |     24 |      1 |      1 | 00:00:00.01 |      48 |      1 |    25 |
-----------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("SLE_NO"=:SLE_NO)

문제 ​

  1. 한 행을 찾는 데 49블록이 드는 까닭을 실행계획의 Starts, Pstart, Pstop과 PK 정의로 설명하시오.
  2. POS를 고치지 않고 칸 하나만 열도록 SQL을 고치고, 고쳐도 결과가 같다는 근거와 그 근거를 지키는 방법을 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자