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

카카오 시범 광고로 들어온 주문 312건을 보는데 네이버 41만 건과 똑같이 블록 1만 9천 개를 읽는다

기초SELECT한빛유통621 / 700

상황 ​

한빛유통 마케팅팀의 「유입 채널 성과」 화면은 랜딩 URL을 목록에서 고르면 그 URL로 들어와 생긴 주문을 일자별로 센다. 화면은 고른 URL을 리터럴로 넣어 SQL을 만든다. 12월 24일에 카카오 시범 광고를 시작했다. 그런데 주문이 312건뿐인 카카오를 골라도 41만 건인 네이버와 똑같이 0.4초가 걸리고 블록 1만 9천 개를 읽는다. 조민우가 통계부터 확인했다. 통계는 어젯밤에 모았고 LND_URL에는 FREQUENCY 히스토그램까지 있었다. "히스토그램이 있는데 왜 카카오를 72만 건으로 볼까요?" 화면 SQL과 이 테이블의 DDL은 조민우가 고칠 수 있다.

테이블과 인덱스 ​

  • T_ORD_LND 주문 유입 기록(이 문제용 · T_ORD_BIG과 1:1 · 웹 로그 배치가 날마다 그날 주문을 한 행씩 적재): 1,000,000행 · 13,320블록 · ORD_SEQ NUMBER · LND_URL VARCHAR2(300) · IN_DTM DATE · 하루 약 910행
  • LND_URL 9종: 회원 혜택 랜딩 https://m.hanbitmall.co.kr/display/promotion/membership-benefit/landing.do?utm_source= 뒤에 채널을 붙인 여섯 개(naver 410,000 · google 160,000 · instagram 100,000 · youtube 40,000 · tiktok 9,688 · kakao 312) · 모바일 메인 https://m.hanbitmall.co.kr/main.do 200,000 · PC 메인 https://www.hanbitmall.co.kr/main.do 60,000 · 상품 목록 https://m.hanbitmall.co.kr/goods/list.do 20,000
  • kakao 312행은 12월 24일 ~ 31일 8일치라 테이블 끝 100블록 안팎에 모여 있다
  • 인덱스 IX_ORD_LND_URL (LND_URL): BLEVEL 2 · 리프 12,180 · 블록마다 여러 URL이 섞여 CF가 90만을 넘는다
  • T_ORD_BIG: 1,000,000행 · 5,826블록 · ORD_DT 1,096일 · IX_ORD_BIG_SEQ (ORD_SEQ) UNIQUE: BLEVEL 2
  • 통계: 어젯밤 수집(FOR ALL COLUMNS SIZE AUTO) · DB는 교재와 같은 23ai · LND_URL의 통계와 히스토그램은 실행계획 아래에 있다

원본 SQL ​

sql
SELECT o.ORD_DT, COUNT(*) AS ord_cnt, SUM(o.ORD_AMT) AS ord_amt
  FROM T_ORD_LND l, T_ORD_BIG o
 WHERE l.LND_URL = 'https://m.hanbitmall.co.kr/display/promotion/membership-benefit/landing.do?utm_source=kakao'
   AND o.ORD_SEQ = l.ORD_SEQ
 GROUP BY o.ORD_DT

실행계획 학습용 예시 · 끝점 길이는 12c 이후(64바이트) 기준 ​

xplan
[utm_source=kakao]
--------------------------------------------------------------------------------------------
| Id  | Operation            | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |           |      1 |        |      8 |00:00:00.41 |   19146 |
|   1 |  HASH GROUP BY       |           |      1 |   1096 |      8 |00:00:00.41 |   19146 |
|*  2 |   HASH JOIN          |           |      1 |   720K |    312 |00:00:00.41 |   19146 |
|*  3 |    TABLE ACCESS FULL | T_ORD_LND |      1 |   720K |    312 |00:00:00.26 |   13320 |
|   4 |    TABLE ACCESS FULL | T_ORD_BIG |      1 |  1000K |  1000K |00:00:00.09 |    5826 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("O"."ORD_SEQ"="L"."ORD_SEQ")
   3 - filter("L"."LND_URL"='https://m.hanbitmall.co.kr/display/promotion/membership-benefit/landing.do?utm_source=kakao')

[같은 SQL · utm_source=naver]  E-Rows 720K · A-Rows 410,000 · HASH JOIN · Buffers 19,146 · 0.52초

[USER_TAB_COL_STATISTICS · T_ORD_LND.LND_URL]
 NUM_DISTINCT  NUM_NULLS  HISTOGRAM   NUM_BUCKETS
            9          0  FREQUENCY             4

[USER_TAB_HISTOGRAMS · T_ORD_LND.LND_URL]
 ENDPOINT_NUMBER  LENGTHB(ENDPOINT_ACTUAL_VALUE)  ENDPOINT_ACTUAL_VALUE
         720,000                              64  https://m.hanbitmall.co.kr/display/promotion/membership-benefit/
         740,000                              40  https://m.hanbitmall.co.kr/goods/list.do
         940,000                              34  https://m.hanbitmall.co.kr/main.do
       1,000,000                              36  https://www.hanbitmall.co.kr/main.do

문제 ​

  1. 3번 줄의 E-Rows 720K를 히스토그램 조회 결과로 손계산하고, 히스토그램이 있는데도 312건인 카카오를 72만 건으로 본 이유와 그 때문에 고른 계획을 설명하시오.
  2. 결과가 바뀌지 않게 하면서 카카오처럼 드문 채널은 인덱스로 찾아가도록 DDL과 SQL을 고치시오.
  3. 히스토그램을 없애는 안과 비교해 고른 방법의 대가를 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자