ROWNUM을 이용한 데이터 기본동작


ROWNUM은 DataBase에 저장되지 않는 의사컬럼으로 참조만 되는 컬럼이다.

ROWNUM = 1은 사용가능하지만 ROWNUM = N (N > 1), ROWNUM > N (N > 1)은 동작하지 않는다.



아래문장은 정상적으로 작동한다.

SQL> WITH ROWNUM_TEST AS (
    SELECT 1 AS C1, 'C' AS C2, 101 AS C3 FROM DUAL
    UNION ALL SELECT 2 AS C1, 'D' AS C2, 102 AS C3 FROM DUAL
    UNION ALL SELECT 3 AS C1, 'E' AS C2, 103 AS C3 FROM DUAL
    UNION ALL SELECT 4 AS C1, 'F' AS C2, 104 AS C3 FROM DUAL
    UNION ALL SELECT 5 AS C1, 'G' AS C2, 105 AS C3 FROM DUAL
    UNION ALL SELECT 6 AS C1, 'H' AS C2, 106 AS C3 FROM DUAL
    UNION ALL SELECT 7 AS C1, 'I' AS C2, 107 AS C3 FROM DUAL
    UNION ALL SELECT 8 AS C1, 'J' AS C2, 108 AS C3 FROM DUAL
    UNION ALL SELECT 9 AS C1, 'K' AS C2, 109 AS C3 FROM DUAL
    UNION ALL SELECT 10 AS C1, 'L' AS C2, 110 AS C3 FROM DUAL
)
SELECT *
FROM (
    SELECT *
    FROM ROWNUM_TEST
    ORDER BY C1
)
WHERE ROWNUM >=1
AND ROWNUM <=5;

C1   C2   C3   
---- ---- ---- 
   1 C     101
   2 D     102
   3 E     103
   4 F     104
   5 G     105

5 rows selected.


아래문장은 정상적으로 작동하지 않는다.

SQL> WITH ROWNUM_TEST AS ( SELECT 1 AS C1, 'C' AS C2, 101 AS C3 FROM DUAL UNION ALL SELECT 2 AS C1, 'D' AS C2, 102 AS C3 FROM DUAL UNION ALL SELECT 3 AS C1, 'E' AS C2, 103 AS C3 FROM DUAL UNION ALL SELECT 4 AS C1, 'F' AS C2, 104 AS C3 FROM DUAL UNION ALL SELECT 5 AS C1, 'G' AS C2, 105 AS C3 FROM DUAL UNION ALL SELECT 6 AS C1, 'H' AS C2, 106 AS C3 FROM DUAL UNION ALL SELECT 7 AS C1, 'I' AS C2, 107 AS C3 FROM DUAL UNION ALL SELECT 8 AS C1, 'J' AS C2, 108 AS C3 FROM DUAL UNION ALL SELECT 9 AS C1, 'K' AS C2, 109 AS C3 FROM DUAL UNION ALL SELECT 10 AS C1, 'L' AS C2, 110 AS C3 FROM DUAL ) SELECT * FROM ( SELECT * FROM ROWNUM_TEST ORDER BY C1 ) WHERE ROWNUM >= 6 AND ROWNUM <= 10; C1 C2 C3 ---- ---- ---- 0 rows selected. ROWNUM C1 C2 C3 ------------ ---- ---- ---- 1 1 C 101 ==> ROWNUM >= 6 AND ROWNUM <= 10 조건에서 조회되지 않고 버려짐. 2 2 D 102 ==> 위의 행이 버려졌으므로 다시 ROWNUM은 1이 되고 조건에 의해 버려짐 3 3 E 103 ==> 이하 동일 4 4 F 104 5 5 G 105 6 6 H 106 7 7 I 107 8 8 J 108 9 9 K 109 10 10 L 110


위의 조회가 정상적으로 되려면 아래와 같이 조회한다.

SQL> WITH ROWNUM_TEST AS (
    SELECT 1 AS C1, 'C' AS C2, 101 AS C3 FROM DUAL
    UNION ALL SELECT 2 AS C1, 'D' AS C2, 102 AS C3 FROM DUAL
    UNION ALL SELECT 3 AS C1, 'E' AS C2, 103 AS C3 FROM DUAL
    UNION ALL SELECT 4 AS C1, 'F' AS C2, 104 AS C3 FROM DUAL
    UNION ALL SELECT 5 AS C1, 'G' AS C2, 105 AS C3 FROM DUAL
    UNION ALL SELECT 6 AS C1, 'H' AS C2, 106 AS C3 FROM DUAL
    UNION ALL SELECT 7 AS C1, 'I' AS C2, 107 AS C3 FROM DUAL
    UNION ALL SELECT 8 AS C1, 'J' AS C2, 108 AS C3 FROM DUAL
    UNION ALL SELECT 9 AS C1, 'K' AS C2, 109 AS C3 FROM DUAL
    UNION ALL SELECT 10 AS C1, 'L' AS C2, 110 AS C3 FROM DUAL
)
SELECT C1, C2, C3 
FROM (
    SELECT ROWNUM RN
        , T1.*
    FROM (
        SELECT * FROM ROWNUM_TEST ORDER BY C1
    ) T1
)
WHERE RN >= 6 AND RN <= 10;

C1   C2   C3   
---- ---- ---- 
   6 H     106
   7 I     107
   8 J     108
   9 K     109
  10 L     110

5 rows selected.



'개발 > DataBase' 카테고리의 다른 글

[Oracle] Null Column 조회 성능개선  (0) 2018.04.29
[Oracle] WHERE절에 number, varchar2 형변환 우선순위  (1) 2018.04.22
[Oracle]Decode 함수2  (0) 2018.04.08
[Oracle] Decode 함수1  (0) 2018.04.08
[Oracle] Regular Expression  (0) 2018.04.04

NULL 조회시 성능개선


1. INDEX가 존재하는 컬럼을 WHERE 조건에 IS NULL로 조회하는 방법.

1.1 해당 컬럼에 Default Value를 지정해서 column_name IS NULL 조회 보다 column_name = default value 형태로 조회한다.

1.2 FBI(Function Based Index) 생성으로 조회시 Index를 사용할 수 있도록 변경한다.


2. INDEX가 존재하는 컬럼을 WHERE 조건에 IS NOT NULL로 조회하는 방법.

2.1 CHAR/VARCHAR2 컬럼의 경우

=> WHERE column_name IS NOT NULL을 WHERE column_name > CHR(0) 형태로 조회한다.

2.2 DATE 타입의 컬럼의 경우

=> WHERE column_name IS NOT NULL을 WHERE column_name > TO_DATE('19000101','YYYYMMDD') 형태로 조회한다.

(19000101은 해당 컬럼에 존재할 수 없는 이전 값)

2.3 NUMBER 타입의 컬럼의 경우

=> WHERE column_name IS NOT NULL을 WHERE column_name >= 0 OR column_name < 0 형태로 조회한다.


'개발 > DataBase' 카테고리의 다른 글

[Oracle] ROWNUM의 기본 동작  (0) 2018.04.30
[Oracle] WHERE절에 number, varchar2 형변환 우선순위  (1) 2018.04.22
[Oracle]Decode 함수2  (0) 2018.04.08
[Oracle] Decode 함수1  (0) 2018.04.08
[Oracle] Regular Expression  (0) 2018.04.04

WHERE절에 number, varchar2 형변환 우선순위


oracle에선 숫자와 문자간의 비교의 경우, 특별히 지정하지 않았다면, 문자를 숫자타입으로 변환하려고 시도합니다.


SQL> desc myemp1
 이름                                           널        유형
 ----------------------------------------- -------- ---------------

 EMPNO                                     NOT NULL NUMBER
 ENAME                                                    VARCHAR2(100)
 DEPTNO                                                  VARCHAR2(1)
 ADDR                                                     VARCHAR2(100)
 SAL                                                       NUMBER
 SUNGBYUL                                             VARCHAR2(1)

* myemp1 데이터건수 2000만건

* empno는 primary key 인덱스, deptno에도 인덱스가 생성되어 있다.

* where절의 비교대상 컬럼의 데이터 타입이 다르면 number로 자동 형 변환된다.
처음예문은 deptno 인덱스를 사용못하는 형태로 변환된다.(인덱스컬럼에 변환이 생김으로 인덱스사용불가)


-- deptno는 varchar2 컬럼
-- 0초
select count(*) from myemp1  
where deptno = '3'

--14초
select count(*) from myemp1  
where deptno = 3

==> 자동형변환

select count(*) from myemp1  
where to_number(deptno) = 3


-- empno 컬럼은 number
--0초
select * from myemp1
where empno = 1234

--0초
select * from myemp1
where empno = '1234'

==> 자동형변환

select * from myemp1
where empno = to_number('1234')


'개발 > DataBase' 카테고리의 다른 글

[Oracle] ROWNUM의 기본 동작  (0) 2018.04.30
[Oracle] Null Column 조회 성능개선  (0) 2018.04.29
[Oracle]Decode 함수2  (0) 2018.04.08
[Oracle] Decode 함수1  (0) 2018.04.08
[Oracle] Regular Expression  (0) 2018.04.04

+ Recent posts