- TABLE
EMP = 100만건
- BIND 변수
:B1 = 3
:B2 = 10
SQL> SELECT x1.*
FROM (SELECT ROWNUM rum
,e.*
FROM (SELECT *
FROM emp
ORDER BY deptno) e
WHERE ROWNUM <= :B2) x1
WHERE x1.rum >= :B1;
이 처럼 SQL에서 추추될 데이터는 많지만, 일부 데이터만 빠르게 추출하기 위해 조건으로 사용할 수 있는것이 ROWNUM이다.
그래서 페이지 처리 시 부분범위 처리가 가능하도록 SQL을 작성하기 위한 필수 요건 중 하나가 바로 ROWNUM이다.
만일 ROWNUM을 부분범위 처리가 되도록 사용하지 않으면, 전체범위 처리로 수행되어 SQL 성능개선에 도움을 주지 못한다.
- TABLE
EMP = 100만건
- BIND 변수
:B1 = 3
:B2 = 10
SQL> SELECT x1.*
FROM (SELECT ROWNUM rum
,e.*
FROM (SELECT *
FROM emp
ORDER BY deptno
) e
) x1
WHERE x1.rum >= :B1
AND x1.rum <= :B2;
- TABLE
EMP = 100만건
- BIND 변수
:B1 = 3
:B2 = 10
SQL> SELECT x1.*
FROM (SELECT ROWNUM rum
,e.*
FROM (SELECT *
FROM emp
ORDER BY deptno
) e
) x1
WHERE x1.rum BETWEEN :B1 AND :B2;
2-1. Script 테스트 데이터 생성
SQL> DROP TABLE t1 PURGE;
1. 생성 요건
- 테이블 데이터 건수는 1,000,000 ROWS
- COLUMN c1은 값의 종류가 1,000,000개, UNIQUE 성격의 컬럼
2. 테이블 생성
SQL> CREATE TABLE t1
AS
SELECT 1000000-(LEVEL-1) c1
,to_char(SYSDATE-(LEVEL-1),'YYYYMMDD') c2
,LEVEL c3
FROM dual
CONNECT BY LEVEL <= 1000000;
3. 각 컬럼에 인덱스 생성 및 통계정보 수집
SQL> CREATE INDEX idx_t1_01 ON t1(c2,c1);
BEGIN
dbms_stats.gather_table_stats(ownname=> 'SCOTT'
,tabname=> 'T1'
,estimate_percent=>99
,method_opt=>'FOR ALL INDEXED COLUMNS'
,granularity=>'ALL'
,CASCADE=>TRUE
,no_invalidate=>FALSE);
END;
/
SQL> SELECT *
FROM t1
WHERE c2 <= to_char(SYSDATE, 'YYYYMMDD')
ORDER BY c2 DESC, c1 DESC;
<교제예제>
- BIND 변수
:B1 = 10
:B2 = 30
SQL> SELECT *
FROM (SELECT ROWNUM rum
,x.*
FROM (SELECT *
FROM t1
WHERE c2 <= TO_CHAR(SYSDATE, 'YYYYMMDD')
ORDER BY c2 DESC, c1 DESC) x
)
WHERE rum >= :B1 AND rum <= :B2
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.001 0 0 0 0
Execute 1 0.000 0.002 0 0 0 0
Fetch 4 1.840 5.092 3321 3343 0 21
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 6 1.840 5.094 3321 3343 0 21
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
21 FILTER (cr=3343 pr=3321 pw=0 time=3715942 us)
21 VIEW (cr=3343 pr=3321 pw=0 time=3715935 us cost=6920 size=44999955 card=999999)
1000000 COUNT (cr=3343 pr=3321 pw=0 time=5457477 us)
1000000 VIEW (cr=3343 pr=3321 pw=0 time=5017693 us cost=6920 size=31999968 card=999999)
1000000 SORT ORDER BY (cr=3343 pr=3321 pw=0 time=4599154 us cost=6920 size=18999981 card=999999)
1000000 TABLE ACCESS FULL T1 (cr=3343 pr=3321 pw=0 time=442169 us cost=967 size=18999981 card=999999)
- BIND 변수
:B1 = 10
:B2 = 30
SQL> SELECT *
FROM (SELECT ROWNUM rum
,x.*
FROM (SELECT /*+ INDEX(T1 IDX_T1_01)*/
*
FROM t1
WHERE c2 <= TO_CHAR(SYSDATE, 'YYYYMMDD')
ORDER BY c2 DESC, c1 DESC) x
)
WHERE rum BETWEEN :B1 AND :B2
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.001 0 0 0 0
Execute 1 0.000 0.002 0 0 0 0
Fetch 4 4.660 14.162 6805 533899 0 21
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 6 4.660 14.166 6805 533899 0 21
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
21 FILTER (cr=533899 pr=6805 pw=0 time=12789371 us)
21 VIEW (cr=533899 pr=6805 pw=0 time=12789360 us cost=538922 size=44999955 card=999999)
1000000 COUNT (cr=533899 pr=6805 pw=0 time=14613582 us)
1000000 VIEW (cr=533899 pr=6805 pw=0 time=14175205 us cost=538922 size=31999968 card=999999)
1000000 SORT ORDER BY (cr=533899 pr=6805 pw=0 time=13760376 us cost=538922 size=18999981 card=999999)
1000000 TABLE ACCESS BY INDEX ROWID T1 (cr=533899 pr=6805 pw=0 time=3309031 us cost=532970 size=18999981 card=999999)
1000000 INDEX RANGE SCAN IDX_T1_01 (cr=3485 pr=3485 pw=0 time=6063613 us cost=3503 size=0 card=998783)(Object ID 127544440)
- BIND 변수
:B1 = 10
:B2 = 30
SQL> SELECT *
FROM (SELECT ROWNUM rum
,x.*
FROM (SELECT /*+ INDEX(T1 IDX_T1_01)*/
*
FROM t1
WHERE c2 <= TO_CHAR(SYSDATE, 'YYYYMMDD')
ORDER BY c2 DESC, c1 DESC) x
WHERE ROWNUM <= :B2
)
WHERE rum >= :B1
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.000 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 4 3.900 9.628 6805 533899 0 21
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 6 3.900 9.628 6805 533899 0 21
Misses in library cache during parse: 0
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
21 VIEW (cr=533899 pr=6805 pw=0 time=9627422 us cost=538922 size=44999955 card=999999)
30 COUNT STOPKEY (cr=533899 pr=6805 pw=0 time=9627451 us)
30 VIEW (cr=533899 pr=6805 pw=0 time=9627415 us cost=538922 size=31999968 card=999999)
30 SORT ORDER BY STOPKEY (cr=533899 pr=6805 pw=0 time=9627381 us cost=538922 size=18999981 card=999999)
1000000 TABLE ACCESS BY INDEX ROWID T1 (cr=533899 pr=6805 pw=0 time=3612942 us cost=532970 size=18999981 card=999999)
1000000 INDEX RANGE SCAN IDX_T1_01 (cr=3485 pr=3485 pw=0 time=3234654 us cost=3503 size=0 card=998783)(Object ID 127544440)
<실제예제>
SQL> SELECT a.*
FROM (SELECT ROWNUM rum
,x.*
FROM T1 x
WHERE c2 <= TO_CHAR(SYSDATE,'YYYYMMDD')
ORDER BY c2 DESC, c1 DESC) a
WHERE a.rum <= :B1
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.001 0 0 0 0
Execute 1 0.000 0.001 0 0 0 0
Fetch 11 1.840 2.472 3321 3343 0 100
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 13 1.840 2.474 3321 3343 0 100
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
100 VIEW (cr=3343 pr=3321 pw=0 time=1696721 us cost=6920 size=44999955 card=999999)
1000000 SORT ORDER BY (cr=3343 pr=3321 pw=0 time=2577140 us cost=6920 size=18999981 card=999999)
1000000 COUNT (cr=3343 pr=3321 pw=0 time=809444 us)
1000000 TABLE ACCESS FULL T1 (cr=3343 pr=3321 pw=0 time=379901 us cost=967 size=18999981 card=999999)
SQL> SELECT a.*
FROM (SELECT ROWNUM rum
,x.*
FROM T1 x
WHERE c2 <= TO_CHAR(SYSDATE,'YYYYMMDD')
AND ROWNUM <= :B2
ORDER BY c2 DESC, c1 DESC) a
WHERE a.rum <= :B1
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.001 0 0 0 0
Execute 1 0.000 0.002 0 0 0 0
Fetch 11 0.010 0.005 14 3 0 100
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 13 0.010 0.007 14 3 0 100
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
100 VIEW (cr=3 pr=14 pw=0 time=4123 us cost=6920 size=44999955 card=999999)
300 SORT ORDER BY (cr=3 pr=14 pw=0 time=4266 us cost=6920 size=18999981 card=999999)
300 COUNT STOPKEY (cr=3 pr=14 pw=0 time=3999 us)
300 TABLE ACCESS FULL T1 (cr=3 pr=14 pw=0 time=3892 us cost=967 size=18999981 card=999999)