Skip to content
튜닝 연습옵티마이저와 통계
OPT-044

라이선스 점검으로 설정 하나를 바꾼 다음 날 고객 주문 내역 API만 다섯 배 느려졌다

기초SELECT이커머스634 / 700

이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.

상황 ​

이커머스 운영팀은 라이선스 점검에서 Tuning Pack을 계약하지 않았다는 것을 확인하고, 어제 저녁 CONTROL_MANAGEMENT_PACK_ACCESS를 DIAGNOSTIC+TUNING에서 DIAGNOSTIC으로 바꿨다. 에러는 하나도 나지 않았다. 오늘 아침부터 「고객 주문 내역」 API(하루 약 2만 번)의 응답이 느려졌다. 다른 API는 그대로다. 소스에는 2년 전 외주 개발자가 넣은 힌트가 있고, 작년 7월 성능 점검 기록에는 "튜닝 어드바이저 권고 1건 수용"이라는 줄이 있다.

테이블과 인덱스 ​

  • orders: 34,908행 · 193블록 · PK(order_id)만 · 고객당 평균 6.7건
  • order_items: 73,498행 · 290블록 · PK(order_item_id)만(order_id 인덱스 없음) · 주문당 평균 2.1줄
  • products: 280행 · 8블록 · PK(product_id)만
  • DBA_SQL_PROFILES: SYS_SQLPROF_0189c2f7a5d30001 · STATUS ENABLED · 작년 7월 생성

원본 SQL ​

sql
SELECT /*+ LEADING(o oi) USE_NL(oi) */
       o.order_id, o.order_date, o.status, oi.product_id, p.name, oi.quantity, oi.unit_price
  FROM orders o, order_items oi, products p
 WHERE o.customer_id  = :cid
   AND oi.order_id    = o.order_id
   AND p.product_id   = oi.product_id

실행계획 학습용 예시 · 교재 18화 §5의 실측 모양 ​

xplan
[오늘 아침 — 주문 7건인 고객]
-----------------------------------------------------------------------------------------------
| Id  | Operation           | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |             |      1 |        |     15 |00:00:00.02 |    2231 |
|*  1 |  HASH JOIN          |             |      1 |     14 |     15 |00:00:00.02 |    2231 |
|   2 |   NESTED LOOPS      |             |      1 |     14 |     15 |00:00:00.02 |    2223 |
|*  3 |    TABLE ACCESS FULL| ORDERS      |      1 |      7 |      7 |00:00:00.01 |     193 |
|*  4 |    TABLE ACCESS FULL| ORDER_ITEMS |      7 |      2 |     15 |00:00:00.02 |    2030 |
|   5 |   TABLE ACCESS FULL | PRODUCTS    |      1 |    280 |    280 |00:00:00.01 |       8 |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("P"."PRODUCT_ID"="OI"."PRODUCT_ID")
   3 - filter("O"."CUSTOMER_ID"=:CID)
   4 - filter("OI"."ORDER_ID"="O"."ORDER_ID")

(Note 절 없음)

[어제 — DBA_HIST_SQL_PLAN 의 같은 SQL_ID]  HASH JOIN 둘 (ORDERS · ORDER_ITEMS · PRODUCTS 를 한 번씩) · 평균 491블록
  Note : SQL profile "SYS_SQLPROF_0189c2f7a5d30001" used for this statement
  프로파일 안의 힌트 : OPTIMIZER_FEATURES_ENABLE(default) · IGNORE_OPTIM_EMBEDDED_HINTS

문제 ​

  1. 에러가 하나도 없었는데 이 API만 느려진 이유를 오늘과 어제의 계획, 프로파일 안의 힌트로 설명하시오.
  2. 팩 설정은 그대로 두고 SQL을 고치시오. 고친 뒤에 정리할 것도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자