Skip to content
튜닝 연습인덱스 사용 조건
IDX-038

매장 이름에 「입구」가 든 열한 곳만 골랐는데 1년 치 주문을 다 읽는다

기초SELECT버거38 / 700

상황 ​

버거원 본사 운영팀의 「매장 주문 추이」 화면은 매장 이름 일부를 넣으면 그 말이 든 매장들의 일별 주문 수를 1년 치 보여 준다. 역세권 매장을 묶어 보려고 '입구', '터미널' 같은 말로 자주 찾는다. 개발자는 "매장 이름을 앞뒤 %로 찾으니 인덱스를 못 탄다. 매장명에 전문 검색 인덱스를 걸어 달라"고 요청했다. 아래는 '입구'로 2013년을 본 계획이다.

테이블과 인덱스 ​

  • SHOP 매장: 200행 · 5블록 · SHOP_NO 'SH0001' · SHOP_NM(홍대입구점, 서울대입구점 …) · '입구'가 든 매장 11곳
  • ORD 주문: 1,000,000행 · 22,422블록(전체 스캔 22,239) · ORD_DT VARCHAR2(8) 2012-01-01 ~ 2013-12-31 · 날짜순 적재 · 매장 한 곳의 1년 주문은 약 2,500건이고 테이블 전체에 흩어져 있다
  • 인덱스 ORD_PK (ORD_NO) · ORD_X01 (ORD_DT, ORD_HMS): 리프 3,774 · SHOP_NO로 시작하는 인덱스는 없다 · 통계 최신

원본 SQL ​

sql
SELECT s.SHOP_NM, o.ORD_DT, COUNT(*) AS ord_cnt
  FROM SHOP s, ORD o
 WHERE s.SHOP_NM LIKE '%' || :v_nm || '%'
   AND o.SHOP_NO = s.SHOP_NO
   AND o.ORD_DT BETWEEN :v_from AND :v_to
 GROUP BY s.SHOP_NM, o.ORD_DT

실행계획 학습용 예시 · 매장 이름은 적재 데이터 그대로 ​

xplan
--------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |   4015 |00:00:00.31 |   22244 |
|   1 |  HASH GROUP BY      |      |      1 |   3650 |   4015 |00:00:00.31 |   22244 |
|*  2 |   HASH JOIN         |      |      1 |  24966 |  27500 |00:00:00.30 |   22244 |
|*  3 |    TABLE ACCESS FULL| SHOP |      1 |     10 |     11 |00:00:00.01 |       5 |
|*  4 |    TABLE ACCESS FULL| ORD  |      1 |    499K|    500K|00:00:00.21 |   22239 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("O"."SHOP_NO"="S"."SHOP_NO")
   3 - filter("S"."SHOP_NM" LIKE '%'||:V_NM||'%')
   4 - filter(("O"."ORD_DT">=:V_FROM AND "O"."ORD_DT"<=:V_TO))

문제 ​

  1. 앞뒤가 %인 LIKE가 이 SQL의 읽은 블록 가운데 얼마를 차지하는지 실행계획으로 설명하고, 전문 검색 인덱스 요청이 맞는지 판단하시오.
  2. 결과가 바뀌지 않게 인덱스를 설계해 고른 매장의 주문만 읽도록 하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자