테마
본사 운영실 상황판은 전 매장의 가장 최근 주문 20건을 보여 주고 10초마다 새로 고친다. 운영실 대형 모니터 4대와 지역 담당 PC 20대가 이 화면을 띄워 두어 하루 약 20만 번 호출된다. DBA가 메시지를 보냈다. "논리 읽기 1위가 이 SQL이에요. ORD_X01 (ORD_DT, ORD_HMS) 인덱스가 있는데 왜 FULL로 읽죠?"
개발자는 일자와 시각이 따로 있으니 둘을 붙여야 정확한 시각순이 된다고 생각해 정렬 키를 ORD_DT || ORD_HMS로 썼다.
ORD 주문: 1,000,000행 · 22,422블록 · 날짜순으로 적재되어 최근 주문은 테이블 끝 블록에 모여 있다 · ORD_NO PK · SHOP_NO 매장 200곳ORD_DT VARCHAR2(8) '20131231' · ORD_HMS VARCHAR2(6) '235958' · 두 컬럼 모두 NOT NULL이고 늘 8자리, 6자리다(0 채움 정상)ORD_PK (ORD_NO), ORD_X01 (ORD_DT, ORD_HMS): BLEVEL 2 · 리프 약 3,500블록 · CF 22,223 · 통계 최신SELECT ORD_NO, SHOP_NO, ORD_DT, ORD_HMS
FROM (SELECT o.ORD_NO, o.SHOP_NO, o.ORD_DT, o.ORD_HMS
FROM ORD o
ORDER BY o.ORD_DT || o.ORD_HMS DESC)
WHERE ROWNUM <= 20
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 20 |00:00:00.27 | 22422 | |
|* 1 | COUNT STOPKEY | | 1 | | 20 |00:00:00.27 | 22422 | |
| 2 | VIEW | | 1 | 1000K| 20 |00:00:00.27 | 22422 | |
|* 3 | SORT ORDER BY STOPKEY| | 1 | 1000K| 20 |00:00:00.27 | 22422 | 4096 (0)|
| 4 | TABLE ACCESS FULL | ORD | 1 | 1000K| 1000K|00:00:00.08 | 22422 | |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=20)
3 - filter(ROWNUM<=20)
ORD_X01이 있는데도 4번 줄이 테이블 전체를 읽고 3번 줄이 정렬하는 이유를 설명하시오.