SQL 튜닝의 시작 (2013년)
INDEX_DESC와 ROWNUM<=1을 함께 사용하지 말자 0 0 99,786

by 구루비스터디 ROWNUM INDEX_DESC [2018.07.14]


INDEX_DESC와 ROWNUM <= 1을 함께 사용하지 말자

  • 최대값, 최소값 추출시 빈번하게 사용되는 방법임.
  • 인덱스의 상태가 Unusable 상태이거나, 인덱스가 존재하지 않으면 잘못된 데이터가 추출될 수 있는 위험 있음.




-- 테이블 생성
CREATE TABLE ROWNUM_T1 AS
SELECT LEVEL AS C1, CHR(65+MOD(LEVEL,26)) AS c2
FROM DUAL CONNECT BY LEVEL <= 500000 ;

-- 인덱스 생성
CREATE INDEX IDX_01 ON ROWNUM_T1 ( C2, C1 ) ;


-- SQL(1)

SELECT /*+ INDEX_DESC(T1 IDX_01) */
       c1
FROM   ROWNUM_T1 t1
WHERE  t1.c2 = 'A'
AND    t1.c1 >= 0
ABD    ROWNUM <= 1;

---------------------------------------------------------------------------------------
| Id  | Operation                    | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |        |     1 |    16 |     3   (0)| 00:00:01 |
|*  1 |  COUNT STOPKEY               |        |       |       |            |          |
|*  2 |   INDEX RANGE SCAN DESCENDING| IDX_01 | 23112 |   361K|     3   (0)| 00:00:01 |
---------------------------------------------------------------------------------------


-- SQL(2)

SELECT c1
FROM  (SELECT /*+ INDEX_DESC(T1 IDX_01) */
              c1
       FROM   ROWNUM_T1 t1
       WHERE  t1.c2 = 'A'
       AND    t1.c1 >= 0
       ORDER BY c2 DESC, c1 DESC
       )
WHERE  ROWNUM <= 1;

----------------------------------------------------------------------------------------
| Id  | Operation                     | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |        |     1 |    13 |     3   (0)| 00:00:01 |
|*  1 |  COUNT STOPKEY                |        |       |       |            |          |
|   2 |   VIEW                        |        | 23112 |   293K|     3   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN DESCENDING| IDX_01 | 23112 |   361K|     3   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

-- SQL(3)

SELECT MAX(c1) AS c1
FROM   ROWNUM_T1 t1
WHERE  t1.c2 = 'A'
AND    t1.c1 >= 0;

---------------------------------------------------------------------------------------
| Id  | Operation                    | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |        |     1 |    16 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE              |        |     1 |    16 |            |          |
|   2 |   FIRST ROW                  |        |     1 |    16 |     3   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN (MIN/MAX)| IDX_01 |     1 |    16 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------------------



  • SQL(1), SQL(2), SQL(3) 성능 차이는 거의 없음.
  • 정합성에 문제가 없는 SQL(2), SQL(3) 을 사용하는 것이 좋음.
"데이터베이스 스터디모임" 에서 2013년에 "SQL튜닝의시작 " 도서를 스터디하면서 정리한 내용 입니다.

- 강좌 URL : http://www.gurubee.net/lecture/3827

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입