인덱스: SAL_DATE + SEQ
1) SELECT *
FROM SALES
WHERE SAL_DEPT = '1230'
AND SEQ = 111;
2) SELECT *
FROM SALES
WHERE SAL_DEPT >= '1230'
AND SEQ >= 111;
1)의 경우 시작점이 있지만 2)의 경우 SEQ의 경우 불필요한 액세스 양이 증가한다.
원하는 방식으로의 처리를 위해서는 SAL_DEPT||SEQ로 조건절을 변경후 함수기반인덱스를 생성하거나
아래와 같이 연쇄 실행계획을 이용한다.
=>
1) SELECT *
FROM SALES
WHERE (SAL_DEPT > '1230') ---------------------(2)
OR (SAL_DEPT = '1230' AND SEQ = 111); ---------------------(1)
연쇄 실행 계획은 WHERE 절에서 가장 나중에 기술한 조건부터 처리하여 완료되면 다음 실행단위로 넘어간다.
시작점을 찾고 스캔하는 모습을 띄고 있으며 각 단위가 부분범위 처리를 하여 효율적이다.
select /*+ index(w cust_name_idx */
rowidtochar(rowid) rid, cust_name, ...
from cust_table w
where :v2 = 'FIRST' and cust_name like :v1 || '%'
and rownum <= 25
union all
select /*+ use_concat index(x cust_name_idx */
rowidtochar(rowid) rid, cust_name, ...
from cust_table x
where :v2 = 'NEXT'
and (cust_name > :v3 or
(cust_name = :v3 and rowid > chartorowid(:v4) ) )
and cust_name like :v1 || '%'
and rownum <= 25
union all
select /*+ use_concat index_desc(x cust_name_idx */
rowidtochar(rowid) rid, cust_name, ...
from cust_table x
where :v2 = 'PREV'
and (cust_name < :v3 or
(cust_name = :v3 and rowid < chartorowid(:v4) ) )
and cust_name like :v1 || '%'
and rownum <= 25
order by cust_name, rid
select bbs_id, 작성일자, 글번호, rnum
from (select /*+ use_concat index_desc(a billboard_uk) */
rownum rnum, bbs_id, 작성일자, 글번호, 글내용
from billboard a
where :sw = 'NEXT'
and bbs_id = :bid
and (작성일자 < :init_dt or
(작성일자 = :init_dt and 글번호 < :v_num) )
and rownum <= 25
union all
select /*+ use_concat index_asc(a billboard_uk) */
(26-rownum) rnum, bbs_id, 작성일자, 글번호, 글내용
from billboard a
where :sw = 'PREV'
and bbs_id = :bid
and (작성일자 > :init_dt or
(작성일자 = :init_dt and 글번호 > :v_num) )
and rownum <= 25
)
order by rnum;
SELECT CDAY, CUST_NM, CID, CSEQ, CTEXT
FROM (SELECT /*+ INDEX_ASC(a IDX01) */
CDAY, CUST_NM, CID, CSEQ, CTEXT
FROM CSTAB a
WHERE :SW = 'FIRST'
AND CDAY BETWEEN :B11 AND :B12
AND ROWNUM <=25
UNION ALL
SELECT /*+ INDEX_DESC(a IDX01) */
CDAY, CUST_NM, CID, CSEQ, CTEXT
FROM CSTAB a
WHERE :SW = 'LAST'
AND CDAY BETWEEN :B11 AND :B12
AND ROWNUM <=25
UNION ALL
SELECT /*+ USE_CONCAT INDEX_ASC(a IDX01) */
CDAY, CUST_NM, CID, CSEQ, CTEXT
FROM CSTAB a
WHERE :SW = 'NEXT'
AND ((CDAY > :B100) OR (CDAY = :B100 AND CID > :B20
OR (CDAY = :B100 AND CID = :B20 AND CSEQ > :B27) )
AND CDAY BETWEEN :B11 AND :B12
AND ROWNUM <=25
UNION ALL
SELECT /*+ USE_CONCAT INDEX_DESC(a IDX01) */
CDAY, CUST_NM, CID, CSEQ, CTEXT
FROM CSTAB a
WHERE :SW = 'PREV'
AND ( (CDAY < :B100) OR (CDAY = :B100 AND CID < :B20
OR (CDAY = :B100 AND CID = :B20 AND CSEQ < :B27) )
AND CDAY BETWEEN :B11 AND :B12
AND ROWNUM <=25 )
ORDER BY CDAY, CID, CSEQ
SELECT RNUM, BBS_ID, CRE_DT, NUM
FROM (SELECT /*+ USE_CONCAT INDEX_DESC(a bbs_idx1) */
ROWNUM RNUM, BBS_ID, CRE_DT, NUM
FROM BILLBOARD a
WHERE :SW = 'NEXT' AND BBS_ID = :V_BBS
AND ( CRE_DT < :V_INIT_DT
OR ( CRE_DT = :INIT_DT AND NUM <= :V_NUM) )
AND ROWNUM <= 201
UNION ALL
특정 페ㅣ지를 액세스하는 SELECT /*+ USE_CONCAT INDEX_ASC(a bbs_idx1) */
((20*10)+2 - ROWNUM) RNUM, BBS_ID, CRE_DT, NUM
FROM BILLBOARD a
WHERE :SW = 'PREV' AND BBS_ID = :V_BBS
AND ( CRE_DT > :V_INIT_DT
OR ( CRE_DT = :INIT_DT AND NUM >= :V_NUM) )
AND ROWNUM <= 201
)
WHERE RNUM IN (1,21,41,61,81,101,121,141,161,181,201)
ORDER BY RNUM
SELECT /*+ USE_CONCAT INDEX_DESC(a bbs_idx1) */ bbs_id, cre_dt, num, c_text
FROM BILLBOARD a
WHERE bbs_id = :bbs
AND ( cre_dt < :v_init_dt
OR ( cre_dt = :v_init_dt AND num <= :v_num ) )
AND ROWNUM <= 20;
SELECT ID, PID, C_TEXT,SUBSTR(PATH,3,3) * 1 PARENT_ID -------(e)
FROM (SELECT ROWNUM RNUM, ID, PID, WRITER,
LPAD(' ', 2*LEVEL-1)||C_TEXT C_TEXT,
SYS_CONNECT_BY_PATH(TO_CHAR(ID,'999'),'/') PATH -------(d)
FROM BILLBOARD
CONNECT BY PID = PRIOR IS
AND ROWNUM <=10 + :CNT -------(b)
START WITH PARENT_SW = 1 -------(a)
AND ID >= :START_ID
)
WHERE RNUM BETWEEN :CNT AND 10+ :CNT -------(c)
AND rownum <= 10;
p490
p492