Skip to content
튜닝 연습인덱스 스캔 효율과 테이블 액세스
ACC-027

DB를 19c로 올린 뒤 하루치 주문 목록은 첫 30줄을 보여 주기 전에 1,378블록을 읽는다

중급SELECT버거102 / 700

상황 ​

버거원 본사 고객센터의 「일별 주문 조회」는 날짜를 하나 고르면 그날 주문을 시각 순으로 보여 준다. 화면은 커서를 연 뒤 30줄씩 가져오고(Fetch), 상담원이 스크롤하면 다음 30줄을 가져온다. 대부분 첫 화면에서 찾는 주문을 본다. 상담원들이 하루 3천 번쯤 연다. 지난 주말 DB를 11g에서 19c로 올린 뒤 첫 화면이 늦게 뜬다. 오과장이 보관해 둔 11g 메모에는 "TABLE ACCESS BY INDEX ROWID, SORT 없음, 첫 화면 33블록"이라고 적혀 있다. SQL과 인덱스는 바꾸지 않았다. 아래는 2012-01-01(1,371건)을 열고 첫 화면만 본 뒤 닫았을 때다.

테이블과 인덱스 ​

  • ORD_RANDOM(운영본): 1,000,000행 · 22,414블록 · 서버 교체 때 순서 없이 다시 적재되어 행마다 다른 블록에 있다 · 하루 약 1,370건 · ORD_DT VARCHAR2(8)
  • 인덱스 ORD_RANDOM_X01 (ORD_DT, ORD_HMS): BLEVEL 2 · 리프 3,774 · CLUSTERING_FACTOR 999,958 · 통계 최신

원본 SQL ​

sql
SELECT o.ORD_NO, o.ORD_HMS, o.SHOP_NO
  FROM ORD_RANDOM o
 WHERE o.ORD_DT = :v_dt
 ORDER BY o.ORD_HMS

실행계획 학습용 예시 · 하루치 Buffers는 교재 04화 실측 ​

xplan
[19c · 지금]
------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Used-Mem |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                |      1 |        |     30 |00:00:00.02 |    1378 |          |
|   1 |  SORT ORDER BY                       |                |      1 |   1370 |     30 |00:00:00.02 |    1378 |   59392  |
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED| ORD_RANDOM     |      1 |   1370 |   1371 |00:00:00.02 |    1378 |          |
|*  3 |    INDEX RANGE SCAN                  | ORD_RANDOM_X01 |      1 |   1370 |   1371 |00:00:00.01 |       7 |          |
------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("O"."ORD_DT"=:V_DT)

[11g · 오과장 메모의 계획]
------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Used-Mem |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                |      1 |        |     30 |00:00:00.01 |      33 |          |
|   1 |  TABLE ACCESS BY INDEX ROWID         | ORD_RANDOM     |      1 |   1370 |     30 |00:00:00.01 |      33 |          |
|*  2 |   INDEX RANGE SCAN                   | ORD_RANDOM_X01 |      1 |   1370 |     30 |00:00:00.01 |       3 |          |
------------------------------------------------------------------------------------------------------------------------

문제 ​

  1. 첫 화면 30줄만 보는데 19c에서는 1,378블록을 읽는 이유를, 두 계획에서 달라진 줄 두 개를 근거로 설명하시오. 정렬할 필요가 없던 SQL에 SORT ORDER BY가 생긴 이유도 설명하시오.
  2. 첫 화면이 다시 30줄만 읽고 뜨도록 SQL을 고치시오. 시스템 전체에서 이 기능을 끄는 방법을 쓰지 않는 이유와, 이 화면에 남는 비용도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자