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

주문 화면이 고객 등급 하나를 확인하는 3블록짜리 조회를 하루 300만 번 보낸다

기초DDL한빛유통127 / 700

상황 ​

쇼핑몰의 장바구니와 주문서 화면은 가격을 다시 계산할 때마다 고객의 등급과 지역을 확인한다. 이 조회는 하루 약 300만 번, 행사 날 피크에는 초당 2천 번 가까이 실행된다. 실행계획은 PK로 한 건을 찾는 3블록짜리라 문제가 없어 보인다. 하지만 AWR의 'SQL ordered by Gets'에서 이 SQL이 1위이고, 행사 날에는 latch: cache buffers chains 대기가 보인다. 박팀장은 "3블록을 더 줄일 수 있느냐"고 묻는다.

테이블과 인덱스 ​

  • M_CUS 고객: 2,000행 · 30블록 · CUS_ID VARCHAR2(40) 'CUS_000123' · 한 행 약 120바이트 · 가입으로 한 달에 수십 명씩 는다(3년 뒤 약 4,000명 예상)
  • PK_M_CUS (CUS_ID): BLEVEL 1 · 리프 6블록 · 통계 최신
  • M_CUS를 읽는 다른 SQL: 등급별 매출 집계(해시 조인의 빌드로 FULL) · 고객 관리 화면의 이름 검색 · CUS_ID를 범위나 LIKE로 찾는 SQL은 없다
  • 고객 정보는 가입과 정보 수정 때만 바뀐다(하루 수십 건)

원본 SQL ​

sql
SELECT CUS_GD, RGN_ID
  FROM M_CUS
 WHERE CUS_ID = :v_cus

실행계획 학습용 예시 · 고객 테이블 규모는 schemas 그대로 ​

xplan
-----------------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |      1 |        |      1 |00:00:00.01 |       3 |
|   1 |  TABLE ACCESS BY INDEX ROWID| M_CUS    |      1 |      1 |      1 |00:00:00.01 |       3 |
|*  2 |   INDEX UNIQUE SCAN         | PK_M_CUS |      1 |      1 |      1 |00:00:00.01 |       2 |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("CUS_ID"=:V_CUS)

문제 ​

  1. 이 SQL이 한 번에 읽는 3블록이 각각 무엇인지 설명하고, 하루 300만 번이면 어떤 블록이 가장 많이 읽히는지 설명하시오.
  2. SQL은 그대로 두고 한 번에 1블록으로 끝나도록 고객 테이블의 구조를 바꾸시오. DDL을 작성하고 그 구조의 제약과 대가를 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자