Oracle/Tuning2018. 3. 4. 15:28

ORDER BY 절에 지정한 정렬 조건에 따라 인덱스로 소트를 회피할 수 없는 경우가 있다.

 

테스트를 위해 아래와 같이 데이터를 생성하자.

-- 1
DROP TABLE t1 PURGE;

CREATE TABLE t1 AS
SELECT DATE '2050-01-01' + ROWNUM - 1 AS c1, 'X' AS c2
  FROM XMLTABLE ('1 to 31');

CREATE INDEX t1_X1 ON t1 (c1);

 

아래 쿼리는 인덱스에 의해 소트가 제거된다.

-- 2
SELECT   *
    FROM t1
   WHERE c1 >= DATE '2050-01-01'
ORDER BY c1;

---------------------------------------------
| Id  | Operation                   | Name  |
---------------------------------------------
|   0 | SELECT STATEMENT            |       |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1    |
|*  2 |   INDEX RANGE SCAN          | T1_X1 |
---------------------------------------------

 

아래 쿼리는 ORDER BY 절의 열이 가공되었기 때문에 소트가 발생한다.

-- 3
SELECT   *
    FROM t1
   WHERE c1 >= DATE '2050-01-01'
ORDER BY TO_CHAR (c1, 'YYYYMMDD');

------------------------------------------------------
| Id  | Operation                            | Name  |
------------------------------------------------------
|   0 | SELECT STATEMENT                     |       |
|   1 |  SORT ORDER BY                       |       |
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED| T1    |
|*  3 |    INDEX RANGE SCAN                  | T1_X1 |
------------------------------------------------------

 

아래 쿼리도 소트가 발생한다. Alias가 우선되기 때문에 TO_CHAR (c1, 'YYYYMMDD')로 정렬되었다.

-- 4
SELECT   TO_CHAR (c1, 'YYYYMMDD') AS c1, c2
    FROM t1
   WHERE c1 >= DATE '2050-01-01'
ORDER BY c1;

------------------------------------------------------
| Id  | Operation                            | Name  |
------------------------------------------------------
|   0 | SELECT STATEMENT                     |       |
|   1 |  SORT ORDER BY                       |       |
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED| T1    |
|*  3 |    INDEX RANGE SCAN                  | T1_X1 |
------------------------------------------------------

 

아래 쿼리도 소트가 발생한다. ORDER BY 절에 열 위치를 지정하면 열 위치가 SELECT 절의 표현식으로 대체되기 때문이다.

-- 5
SELECT   TO_CHAR (c1, 'YYYYMMDD') AS c1, c2
    FROM t1
   WHERE c1 >= DATE '2050-01-01'
ORDER BY 1;

------------------------------------------------------
| Id  | Operation                            | Name  |
------------------------------------------------------
|   0 | SELECT STATEMENT                     |       |
|   1 |  SORT ORDER BY                       |       |
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED| T1    |
|*  3 |    INDEX RANGE SCAN                  | T1_X1 |
------------------------------------------------------

 

해법은 간단하다. ORDER BY 절의 열을 테이블이나 Alias로 한정해주면 된다.

-- 6
SELECT   TO_CHAR (c1, 'YYYYMMDD') AS c1, c2
    FROM t1
   WHERE c1 >= DATE '2050-01-01'
ORDER BY t1.c1;

---------------------------------------------
| Id  | Operation                   | Name  |
---------------------------------------------
|   0 | SELECT STATEMENT            |       |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1    |
|*  2 |   INDEX RANGE SCAN          | T1_X1 |
---------------------------------------------


'Oracle > Tuning' 카테고리의 다른 글

소트 #3 - IN 절  (0) 2018.03.04
소트 #2 - 조인 정렬 조건  (0) 2018.03.04
블록 그래뉼과 파티션 그래뉼  (0) 2018.03.03
PQ_REPLICATE 힌트  (1) 2018.03.03
Nonprefix 로컬 인덱스와 소트 #2  (1) 2018.03.02
Posted by 정희락_