메뉴 건너뛰기

bysql.net

1. 소트 수행 원리

2011.06.12 19:06

휘휘 조회 수:5732

(1) 소트 수행 과정

  • SORT AREA 할당의 두 유형 (PGA 내)
    • IN-MEMORY SORT(메모리 소트; INTERNAL SORT) : 전체 데이터 정렬 작업을 메모리 내에서 완료
    • TO-DISK SORT (디스크 소트;EXTERNAL SORT): 항당된 SORT AREA 내에서 정렬이 불가능하여 디스크 공간까지 사용

  • 소트의 3개지 방식
    • Optimal 소트 : 소트 오퍼레이션이 메모리 내에서만 이루어짐
    • Onepass 소트: 정렬 대상 집합이 디스크에 한번만 쓰임
    • Multipass 소트 : 정렬 대상 집합이 디스크에 여러번 쓰임




CBO ORACLE원리 13장 참조)
http://www.bysql.net/?document_srl=1107





  • 디스크 소트과정

sgiaz1XULKGse6n6nb6UGGQ.png







  • Sort Run: Sort Area가 찰때마다 정렬된 중간 집합을 Temp Tablespace의 Temp 세그먼트에 임시저장
  • Run Merge : Temp 영역에 저장해둔 중간 단계 집합을 Merge 



(2) 소트 오퍼레이션 측정





SQL> create table t_emp
as
select *
from scott.emp,(select rownum no from dual connect by level <= 100000) ;
 2    3    4

Table created.

SQL> SQL> alter session set workarea_size_policy=manual;

Session altered.

SQL> alter session set sort_area_size=104875;

Session altered.

SQL> set autot on;
SQL> select *
 2  from (
 3     select no,empno,ename, job,mgr,sal
 4             ,avg(sal) over (partition by to_char(no),deptno) avg_sal
 5     from t_emp
 6  )
 7  where no =1
 8  order by sal desc;

       NO      EMPNO ENAME      JOB              MGR        SAL    AVG_SAL
---------- ---------- ---------- --------- ---------- ---------- ----------
        1       7839 KING       PRESIDENT                  5000 2916.66667
        1       7902 FORD       ANALYST         7566       3000       2175
        1       7788 SCOTT      ANALYST         7566       3000       2175
        1       7566 JONES      MANAGER         7839       2975       2175
        1       7698 BLAKE      MANAGER         7839       2850 1566.66667
        1       7782 CLARK      MANAGER         7839       2450 2916.66667
        1       7499 ALLEN      SALESMAN        7698       1600 1566.66667
        1       7844 TURNER     SALESMAN        7698       1500 1566.66667
        1       7934 MILLER     CLERK           7782       1300 2916.66667
        1       7521 WARD       SALESMAN        7698       1250 1566.66667
        1       7654 MARTIN     SALESMAN        7698       1250 1566.66667

       NO      EMPNO ENAME      JOB              MGR        SAL    AVG_SAL
---------- ---------- ---------- --------- ---------- ---------- ----------
        1       7876 ADAMS      CLERK           7788       1100       2175
        1       7900 JAMES      CLERK           7698        950 1566.66667
        1       7369 SMITH      CLERK           7902        800       2175

14 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 4263631893
--------------------------------------------------------------------------------------
| Id  | Operation            | Name  | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |       |  1532K|   113M|       |   366K  (1)| 00:42:24 |
|   1 |  SORT ORDER BY       |       |  1532K|   113M|   140M|   366K  (1)| 00:42:24 |
|*  2 |   VIEW               |       |  1532K|   113M|       |   184K  (1)| 00:21:24 |
|   3 |    WINDOW SORT       |       |  1532K|   113M|   140M|   184K  (1)| 00:21:24 |
|   4 |     TABLE ACCESS FULL| T_EMP |  1532K|   113M|       |  3522   (2)| 00:00:25 |
--------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

  2 - filter("NO"=1)

Note
-----
  - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
        74  recursive calls
       722  db block gets
      9196  consistent gets
     59414  physical reads
         0  redo size
      1299  bytes sent via SQL*Net to client
       420  bytes received via SQL*Net from client
         2  SQL*Net roundtrips to/from client
         1  sorts (memory)
         1  sorts (disk)
        14  rows processed



  • 두번의 소트 오프레이션 이 발생하여 한번은 메모리 내에서 처리 , 한번은 디스크 소트갑 발생
  • 59414번의 physical reads가 발생하였으며 consistent gets 와 db block get의 값보다 큰것으로 보아
    디스크 소트 과정에서 발생한 i/o까지 포함







sqltrace


 ********************************************************************************

 select *
 from (
    select no,empno,ename, job,mgr,sal
            ,avg(sal) over (partition by to_char(no),deptno) avg_sal
    from t_emp
 )
 where no =1
order by sal desc

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.01       0.01          0         81          0           0
Execute      3      0.00       0.00          0          0          0           0
Fetch        6     23.00      33.63      81864      27588         63          42
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       12     23.01      33.64      81864      27669         63          42

Misses in library cache during parse: 2
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Rows     Row Source Operation
-------  ---------------------------------------------------
    14  SORT ORDER BY (cr=9196 pr=27292 pw=18099 time=0 us cost=67077 size=119496000 card=1532000)
    14   VIEW  (cr=9196 pr=27292 pw=18099 time=78 us cost=35299 size=119496000 card=1532000)
1400000    WINDOW SORT (cr=9196 pr=27292 pw=18099 time=6864833 us cost=35299 size=119496000 card=1532000)
1400000     TABLE ACCESS FULL T_EMP (cr=9196 pr=9192 pw=0 time=1396415 us cost=3522 size=119496000 card=1532000)


Elapsed times include waiting on following events:
 Event waited on                             Times   Max. Wait  Total Waited
 ----------------------------------------   Waited  ----------  ------------
 SQL*Net message to client                       6        0.00          0.00
 direct path read                              219        0.00          0.27
 direct path write temp                       4422        0.06         11.41
 direct path read temp                       54025        0.00          0.64
 SQL*Net message from client                     6        0.00          0.00
 asynch descriptor resize                       14        0.00          0.00
********************************************************************************


* 4번이상 수행후 trace했음에도 Full table scan에  pr 있음 ㅡㅡ;;;
windows sort 단계의 pr 27292, pw=18099 개의 블록 읽고 쓰기 발생




  • auto trace, sql trace외의 통계확인방법
    • v$sysstat/v$sessatat / v$mystat
    • v$sort_segment
    • v$sort_usage
    • v$temp_extent_pool




(3) Sort Area

  • 데이터 정렬을 위해 사용
  • 소트오프레이션이 진행되는 동안 공간이 부족해질때마다 청크 단위(db_block_size) 로 할당
  • 세셜별 사용가능 최대공간
    • 9i 이전 : sort_area_size 
    • 9i 이후 : workarea_size_policy - auto (기본값; 오라클 자체 결정) ,7절 참조


sort_area_retained_size

  • 데이터 정렬후 결과집합을 모두 Fetch 할때까지 유지할 sort area 크기 지정
  • 초과 데이터는 temp 세그먼트에 저장후 fetch 과정에서 다시 읽힘
  • sort_area_size가 충분히 커더라도 이 파라미터가 결과집합보다 작으면 I/O 발생
  • 0 으로 설정하면 크기 유지의 의미





  • PGA
    • Process/Program/Private Global Area
    • 프로세스에 종속적인 고유 데이터를 저장하는 용도로 사용 (1프로세스, 1PGA)
    • 다른프로세스와 공유되지 않는 독립 메모리 공간
    • 래치 매커니즘이 필요없어 동일개수의 블록이라도 SGA버퍼 캐시보다 빠름
    • 세션과 독립적인 프로세스만의 정보 관리


  • UGA
    • 세션을 위한 독립적인 메모리 공간 (User Global Area), 1세션 1UGA
    • Dedicated Server
      • 프로세서와 세션 1:1
      • PGA 에 할당
    • Shared Server  or MTS
      • 프로세서와 세션 1:M
      • SGA에 할당
      • Large Pool 이 설정됐을 경우: Large Pool
      • Large Pool 이 설정되지 않을 경우 : Shared Pool 
    • 프로세스와 독립적인 세션만의 정보 관리
    • 하나의 데이터베이스 Call을 넘어서 다음 Call까지 계속 참조될 경우 

  • CGA
    • PGA 에 할당
    • Call Global Area
    • Call이 진행동안 필요한 데이터를 담음
    • Parse Call,Execute Call, Fetch Call 마다 매번 할당
    • Recursive Call발생시에도 단계별로 CGA추가 할당
    • 하나의Call이 끝나면 해제되 PGA로 반환



Sort Area 할당 위치
  • SQL 문 종류와 소트 수행 단계에 따라 다름
  • DML 
    • 하나의 Execute Call내에서 모든 데이터 처리 완료, call 완료순간 자동으로 커서가 닫힘( CGA에 할당)
  • SELECT 문 마지막 단계: 계속 이어지는 Fetch Call에서 사용, Sort_area_retained_size제약이 없다면 
  • 마지막 소트라면 UGA에 할당
  • 마지막 단계보다 앞선 데이터는 첫번째 Fetch Call 내에서만 사용, CGA할당.




select /*+ ordred use_merge (e) */
   d.deptno, d.dname, e.ename, e.sal, e.job
   ,rank() over(partition by d.deptno order by e.sal) sal_rank
from scott.dept d, scott.emp e
where d.deptno=e.deptno
order by e.sal desc;


Execution Plan
----------------------------------------------------------
Plan hash value: 2862614994

------------------------------------------------------------------------------------------
| Id  | Operation                      | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |         |    14 |   476 |     9  (34)| 00:00:01 |
|   1 |  SORT ORDER BY                 |         |    14 |   476 |     9  (34)| 00:00:01 | -> UGA
|   2 |   WINDOW SORT                  |         |    14 |   476 |     9  (34)| 00:00:01 | -> CGA
|   3 |    MERGE JOIN                  |         |    14 |   476 |     7  (15)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| DEPT    |     4 |    52 |     2   (0)| 00:00:01 |
|   5 |      INDEX FULL SCAN           | PK_DEPT |     4 |       |     1   (0)| 00:00:01 |
|*  6 |     SORT JOIN                  |         |    14 |   294 |     5  (20)| 00:00:01 | -> CGA
|   7 |      TABLE ACCESS FULL         | EMP     |    14 |   294 |     4   (0)| 00:00:01 |
------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  6 - access("D"."DEPTNO"="E"."DEPTNO")
      filter("D"."DEPTNO"="E"."DEPTNO")







요약


1. dml 문장 수행 시 발생하는 소트는 CGA에서 수행

2. select 문장 수행시

(1) 쿼리 중간 단계의 소트

cga에서 수행. sort_area_retained_size제약이 있다면 다음단계로 넘어가기

전에 이값을 초과하는 cga영역을 반환

(2) 결과 집합을 출력하기 직전 단계에서 수행하는 소트

1. sort_area_retained-size 제약이 있다면, cga에서 소트 수행

이제약만큼의 uga를 할당해 정렬된 결과를 담았다가 이후
fetch call에서 array 단위로 전송

2.sort_area_retained_size제약이 없다면, 곧바로 uga에서 소트 수행


  • cga에 할당된 sort area는 하나의 call이 끝나자마자 pga에 반환
  • uga에 할당된 sort area는 마지막 로우가 fetch될때 비로서 uga  heap에 반환, 대부분 부모 heap(pga,sga)에도 즉각 반환


(4) 소트 튜닝 요약


  • 소트 오프레이션은 데이터량이 많을 경우 디스크 i/o를 유발시키고 이로 인해 성능의 손실과
    부분범위처리의 불가능 등의 문제가 있으므로 가능하면 소트를 발생하지 않도록 sql을 작성해야하며
    불가피할경우 메모리 내에서 완료할수 있도록 해야함
    • 데이터 모델 측면에서의 검토
    • 소트가 발생하지 않도록 sql작성
    • 인덱스를 이용한 소트 연산 대체
    • sort area를 적게 사용하도록 sql작성
    • sort area크기 조정



  • 오라클 고도화 원리와 해법 2 (bysql.net 2011년 1차 스터디)
  • 작성자: 테스트 (아이디)
  • 최초작성일: 2011년 6월 12일
  • 본문서는 bysql.net 스터디 결과입니다 .본 문서를 인용하실때는 출처를 밝혀주세요. http://www.bysql.net
  • 문서의 잘못된 점이나 질문사항은 본문서에 댓글로 남겨주세요. ^^

번호 제목 글쓴이 날짜 조회 수
60 Front Page file 운영자 2011.02.16 149419
59 3. 인덱스 파티셔닝 darkbeom 2011.06.20 53824
58 3. 다양한 인덱스 스캔 방식 file 멋진넘 2011.02.19 33807
57 8. 통계정보 Ⅱ [1] 멋진넘 2011.04.30 31075
56 2. 파티션 Pruning 실천하자 2011.06.22 26018
55 3. 뷰 Merging 실천하자 2011.05.15 23381
54 3. 해시 조인 file darkbeom 2011.03.21 21530
53 2. 서브쿼리 Unnesting darkbeom 2011.05.16 19700
52 4. 통계정보 Ⅰ darkbeom 2011.04.26 18091
51 7. 인덱스 스캔 효율 [1] 휘휘 2011.03.09 16889
50 7. Sort Area 크기 조정 실천하자 2011.06.14 15067
49 4. 테이블 Random 액세스 부하 [1] file darkbeom 2011.02.24 14677
48 4. 조인 순서의 중요성 운영자 2011.03.28 14240
47 1. 인덱스 구조 [1] file 실천하자 2011.02.16 14190
46 1. 기본 개념 멋진넘 2011.06.28 13396
45 8. 고급 조인 테크닉-1 [1] file darkbeom 2011.04.04 13265
44 9. 비트맵 인덱스 file 실천하자 2011.03.06 12342
43 1. 옵티마이저 file 실천하자 2011.04.18 11211
42 6. 히스토그램 실천하자 2011.04.25 10917
41 6. Sort Area를 적게 사용하도록 SQL 작성 file 실천하자 2011.06.14 8857