날짜 조회 안티 패턴 마지막 글이다.
테스트를 위해 아래와 같이 테이블을 생성하자.
-- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 AS SELECT TRUNC (SYSDATE) - ROWNUM AS c1 FROM XMLTABLE ('1 to 30'); CREATE INDEX t1_x1 ON t1 (c1);
-- 2 SELECT c1 , TRUNC (SYSDATE) AS dt , ROUND (MONTHS_BETWEEN (TRUNC (SYSDATE), c1) * 30.5) AS dc FROM t1 WHERE ROUND (MONTHS_BETWEEN (TRUNC (SYSDATE), c1) * 30.5) BETWEEN 28 AND 30; C1 DT DC ------------------- ------------------- -- 2019-07-19 00:00:00 2019-08-16 00:00:00 28 2019-07-18 00:00:00 2019-08-16 00:00:00 29 2019-07-17 00:00:00 2019-08-16 00:00:00 30 3 행이 선택되었습니다. ---------------------------------- | Id | Operation | Name | ---------------------------------- | 0 | SELECT STATEMENT | | |* 1 | TABLE ACCESS FULL| T1 | ----------------------------------
의미를 해석해보면 아래 쿼리처럼 c1이 현재일로부터 28일에서 30일 전 날짜에 해당하는 행을 조회하는 것으로 알 수 있다.
-- 3 SELECT c1 , TRUNC (SYSDATE) AS dt , TRUNC (SYSDATE) - c1 AS dc FROM t1 WHERE TRUNC (SYSDATE) - c1 BETWEEN 28 AND 30; C1 DT DC ------------------- ------------------- -- 2019-07-19 00:00:00 2019-08-16 00:00:00 28 2019-07-18 00:00:00 2019-08-16 00:00:00 29 2019-07-17 00:00:00 2019-08-16 00:00:00 30 3 행이 선택되었습니다.
아래와 같이 날짜의 범위를 조회하면 인덱스를 사용할 수 있다. 쿼리도 훨씬 간결하다.
-- 4 SELECT c1 , TRUNC (SYSDATE) AS dt , TRUNC (SYSDATE) - c1 AS dc FROM t1 WHERE c1 BETWEEN TRUNC (SYSDATE) - 30 AND TRUNC (SYSDATE) - 28; C1 DT DC ------------------- ------------------- -- 2019-07-19 00:00:00 2019-08-16 00:00:00 28 2019-07-18 00:00:00 2019-08-16 00:00:00 29 2019-07-17 00:00:00 2019-08-16 00:00:00 30 3 행이 선택되었습니다. ----------------------------------- | Id | Operation | Name | ----------------------------------- | 0 | SELECT STATEMENT | | |* 1 | FILTER | | |* 2 | INDEX RANGE SCAN| T1_X1 | -----------------------------------
'Oracle > Tuning' 카테고리의 다른 글
Plan Hash Value (0) | 2019.08.26 |
---|---|
MERGE JOIN CARTESIAN (0) | 2019.08.23 |
날짜 조회 안티 패턴 #2 (0) | 2019.08.16 |
날짜 조회 안티 패턴 #1 (0) | 2019.08.14 |
아우터 조인과 OR 조건 (0) | 2019.08.14 |