소트 데이터 줄이기

-- 1번
select lpad(상품번호, 30) || lpad(상품명, 30) || lpad(고객ID, 10)
    || lpad(고객명, 20) || to_char(주문일시, 'yyyymmdd hh24:mi:ss')
from   주문상품
where  주문일시 between :start and :end
order by 상품번호

-- 2번
select lpad(상품번호, 30) || lpad(상품명, 30) || lpad(고객ID, 10)
    || lpad(고객명, 20) || to_char(주문일시, 'yyyymmdd hh24:mi:ss')
from (
    select 상품번호, 상품명, 고객ID, 고객명, 주문일시
    from   주문상품
    where  주문일시 between :start and :end
    order by 상품번호
)
-- 1번
SELECT *
FROM   예수금원장
ORDER BY 총예수금 desc

Execution Plan
---------------------------------------------------------------------------------------
0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=184K Card=2M Bytes=716M)
1  0     SORT (ORDER BY) (Cost=184K Card=2M Bytes=716M)
2  1       TABLE ACCESS (FULL) OF '예수금원장' (TABLE) (Cost=25K Card=2M Bytes=716M)

-- 2번
SELECT 계좌번호, 총예수금
FROM   예수금원장
ORDER BY 총예수금 desc

Execution Plan
---------------------------------------------------------------------------------------
0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=31K Card=2M Bytes=17M)
1  0     SORT (ORDER BY) (Cost=31K Card=2M Bytes=17M)
2  1       TABLE ACCESS (FULL) OF '예수금원장' (TABLE) (Cost=24K Card=2M Bytes=17M)

Top N 쿼리의 소트 부하 경감 원리

select *
from (
    select rownum no, a.*
    from
    (
        select 거래일시, 체결건수, 체결수량, 거래대금
        from   종목거래
        where  종목코드 = 'KR123456'
        and    거래일시 >= '20180304'
        order by 거래일시
    ) a
    where  rownum <= (:page * 10)
)
where no >= (:page-1)*10 + 1

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           2    0.078        0.083         0        690          0      10
------- --------- -------- ------------ --------- ---------- ---------- -------
Total           4    0.078        0.084         0        690          0      10

Rows  Row Source Operation
----- -----------------------------------------------------------------------
    0 STATEMENT
   10  COUNT STOPKEY (cr=690 pr=0 pw=0 time=83318 us)
   10   VIEW (cr=690 pr=0 pw=0 time=83290 us)
   10    SORT ORDER BY STOPKEY (cr=690 pr=0 pw=0 time=83264 us)
49857     TABLE ACCESS FULL 종목거래(cr=690 pr=0 pw=0 time=299191 us)
Statistics
---------------------------
0  recursive calls
0  db block gets
690  consistent gets
0  physical reads
...  ...
1  sorts (memory)
0  sorts (disk)

Top N 쿼리가 아닐 때 발생하는 소트 부하

select *
from (
    select rownum no, a.*
    from
    (
        select 거래일시, 체결건수, 체결수량, 거래대금
        from   종목거래
        where  종목코드 = 'KR123456'
        and    거래일시 >= '20180304'
        order by 거래일시
    ) a
)
where no between (:page-1)*10 + 1 and (:page * 10)

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           2    0.281        0.858       698        690         14      10
------- --------- -------- ------------ --------- ---------- ---------- -------
Total           4    0.281        0.858       698        690         14      10

Rows  Row Source Operation
----- -----------------------------------------------------------------------
    0 STATEMENT
   10  VIEW (cr=690 pr=698 pw=698 time=357962 us)
49857   COUNT (cr=690 pr=698 pw=698 time=1604327 us)
49857    VIEW (cr=690 pr=698 pw=698 time=1205452 us)
49857     SORT ORDER BY (cr=690 pr=698 pw=698 time=756723 us)
49857      TABLE ACCESS FULL 종목거래(cr=690 pr=0 pw=0 time=249345 us)
Statistics
---------------------------
6  recursive calls
14  db block gets
690  consistent gets
698  physical reads
...  ...
0  sorts (memory)
1  sorts (disk)

분석함수에서의 Top N 소트

select 장비번호, 변경일자, 변경순번, 상태코드, 메모
from (select 장비번호, 변경일자, 변경순번, 상태코드, 메모
           , max(변경순번) over (partition by 장비번호) 최종변경순번
      from   상태변경이력
      where  변경일자 = :upd_dt)
where 변경순번 = 최종변경순번

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           2    2.750        9.175     13456       4536          9      10
------- --------- -------- ------------ --------- ---------- ---------- -------
Total           4    2.750        9.175     13456       4536          9      10

Rows  Row Source Operation
----- -----------------------------------------------------------------------
    0 STATEMENT
   10  VIEW (cr=4536 pr=13456 pw=8960 time=4437847 us)
498570  WINDOW SORT (cr=4536 pr=13456 pw=8960 time=9120662 us)
498570   TABLE ACCESS FULL 상태변경이력 (cr=4536 pr=0 pw=0 time=1994341 us)
select 장비번호, 변경일자, 변경순번, 상태코드, 메모
from (select 장비번호, 변경일자, 변경순번, 상태코드, 메모
           , rank() over(partition by 장비번호 order by 변경순번 desc) rnum
      from   상태변경이력
      where  변경일자 = :upd_dt)
where rnum = 1

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           2    0.969        1.062        40       4536         42      10
------- --------- -------- ------------ --------- ---------- ---------- -------
Total           4    0.969        1.062        40       4536         42      10

Rows  Row Source Operation
----- -----------------------------------------------------------------------
    0 STATEMENT
   10  VIEW (cr=4536 pr=40 pw=40 time=1061996 us)
  111   WINDOW SORT PUSHED RANK (cr=4536 pr=40 pw=40 time=1061971 us)
498570    TABLE ACCESS FULL 상태변경이력 (cr=4536 pr=0 pw=0 time=1495760 us)