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

대문자 함수 인덱스까지 만들었는데 로그인 조회는 여전히 고객 테이블을 다 읽는다

중급DDL이커머스16 / 700

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

상황 ​

신규 이커머스의 로그인과 비밀번호 찾기 API는 이메일로 고객을 찾는다. 가입 화면이 입력한 대소문자를 그대로 저장해 와서, 개발팀은 대소문자를 무시하려고 양쪽을 LOWER로 감쌌다. 하루 약 30만 번 호출된다. 지난주 개발자 한 명이 "함수 인덱스를 만들면 된다더라"라며 UPPER(email) 인덱스를 만들었는데 계획은 그대로다.

테이블과 인덱스 ​

  • customers: 5,230행 · 51블록 · email VARCHAR2 · 유니크 제약 UQ_CUSTOMERS_EMAIL (email)
  • 문제 설정: 대문자가 섞인 이메일 312건 · 대소문자만 다르고 같은 주소인 계정 2쌍(Kim.J@…와 kim.j@… 같은 경우)
  • 인덱스 PK_CUSTOMERS (customer_id) · UQ_CUSTOMERS_EMAIL (email) · IX_CUS_EMAIL_UP (UPPER(email)): 지난주 생성 · 통계 최신

원본 SQL ​

sql
SELECT customer_id, name, grade
  FROM customers
 WHERE LOWER(email) = LOWER(:email)

실행계획 학습용 예시 ​

xplan
------------------------------------------------------------------------------------------
| Id  | Operation         | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |      1 |        |      1 |00:00:00.01 |      51 |
|*  1 |  TABLE ACCESS FULL| CUSTOMERS |      1 |     52 |      1 |00:00:00.01 |      51 |
------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(LOWER("EMAIL")=LOWER(:EMAIL))

문제 ​

  1. 이메일에 유니크 인덱스와 UPPER(email) 함수 기반 인덱스가 다 있는데도 테이블 전체를 읽는 이유를 설명하시오.
  2. 대소문자를 무시하는 규칙은 지키면서 한 건만 찾아가도록 DDL과 SQL을 작성하시오. 이미 있는 데이터 때문에 생기는 문제와 그 처리도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자