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

영수증 번호 하나를 찾는데 인덱스를 24번 연다

중급SELECT버거377 / 700

상황 ​

매장 POS의 「영수증 재조회」는 환불이나 재출력, 포인트 확인 때 영수증 바코드(주문번호)를 찍어 조회한다. 200개 매장에서 하루 약 6만 번 호출된다. 파티션 테이블로 옮긴 뒤 DB CPU 상위 SQL 목록에 이 SQL이 올라왔다. 영수증 바코드에는 주문번호만 있다. 주문일은 영수증에 찍혀 있지만 POS가 넘기지 않는다. 넘기게 하려면 POS 배포(200개 매장, 다음 분기)가 필요하다.

테이블과 인덱스 ​

  • ORD_RANGE: 1,000,000행 · PARTITION BY RANGE (ORD_YM) 월별 25칸(P201201 ~ P201312 + 빈 P_DEFAULT) · 한 달 약 41,000행
  • 인덱스 ORD_RANGE_PK (ORD_NO, ORD_YM)는 LOCAL이다(PK를 LOCAL로 만들려고 파티션 키를 뒤에 붙였다). ORD_RANGE_X01 (ORD_DT, ORD_HMS)도 LOCAL이다. 두 인덱스 모두 칸마다 높이가 2다.
  • 매달 1일에 보관 기간이 지난 달을 정리한다(월 1회). 이 작업은 칸째 들어내는 파티션 DDL로 바꾸기로 했다.
  • 옮기기 전 파티션 없는 ORD에서는 ORD_PK (ORD_NO)로 4블록을 읽었다.
  • 아래는 :ord_no = 777777(2013년 7월 주문, 19번 칸)로 실행한 결과다.

원본 SQL ​

sql
SELECT ORD_NO, ORD_YM, ORD_DT, ORD_HMS, SHOP_NO
  FROM ORD_RANGE
 WHERE ORD_NO = :ord_no

실행계획 실측 · 교재 14화 ​

xplan
--------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name         | Starts | E-Rows | A-Rows |    A-Time   | Buffers | Pstart | Pstop |
--------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |              |      1 |        |      1 | 00:00:00.01 |      50 |        |       |
|   1 |  PARTITION RANGE ALL                |              |      1 |      1 |      1 | 00:00:00.01 |      50 |      1 |    25 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID | ORD_RANGE    |     24 |      1 |      1 | 00:00:00.01 |      50 |      1 |    25 |
|*  3 |    INDEX RANGE SCAN                 | ORD_RANGE_PK |     24 |      1 |      1 | 00:00:00.01 |      49 |      1 |    25 |
--------------------------------------------------------------------------------------------------------------------------------

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

문제 ​

  1. 한 행을 찾는 데 50블록이 드는 까닭을 실행계획의 Starts, Pstart, Pstop과 인덱스 정의로 설명하시오.
  2. 고치는 방법 두 가지(조건을 더한다, 인덱스를 바꾼다)를 SQL로 작성하고, 각각의 대가와 이 화면에 어느 쪽을 권할지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자