Post List

레이블이 SQLP인 게시물을 표시합니다. 모든 게시물 표시
레이블이 SQLP인 게시물을 표시합니다. 모든 게시물 표시

2016년 3월 5일 토요일

2016년 3월 5일 20회 SQLP 시험후기

20회 SQLP 시험후기


1. 시험일시

2016년 3월 5일 오후 1시부터 4시까지

2. 학습기간

2016년 1월 10일경부터 약 2달간

3. 공부방법

  • SQLP 가이드 1번 읽기 : 2주
  • SQLP 가이드 Blog에 정리 : 3주 (정리 후 다시 읽어보진 않았음)
  • 기출문제 풀이 : 나머지 기간동안

4. 본인소개

  • 나이 : 40세
  • IT경력 : 8년차
  • 현재 WareValley에서 Orange라는 DB 관리툴 개발팀에 소속

솔직히 위에 적은 것은 별로 안 궁금하시죠 ? 20회 시험 문제에 대해 말씀드리겠습니다.
잊어버리기 전에 서술형 부터 먼저 설명드릴께요.
서술형 1번은 SQL문과 Trace 결과를 주고 Tuning하라는 문제였습니다.
정확한 복기는 힘들듯 하고, 그냥 제가 문제를 풀면서 든 생각을 적겠습니다.
Table a, b, c가 있고 3개를 NL Join 한 것으로 Trace 결과가 나왔습니다.
a 와 b 를 먼저 join 했는데, a의 column 하나를 like 'ZZ%'로 비교를 했습니다. cr=2에 rows도 100건 정도여서 별로 비효율이 없어보였습니다.
c의 index range scan에서 cr=2300 가량에 rows 가 50건 정도로 여기 index를 수정해야 겠구나 생각이 들었습니다.
그래서 index 추가하고 해당 index 사용하는 것으로 sql을 시험지에 작성한 뒤에 2번 문제를 풀었습니다.
1번 문제를 답안지에 옮겨 적는 중 이상한걸 하나 발견했습니다.
SELECT b. ... , c. ...
  FROM a, b, c
 WHERE a.ProdCode LIKE 'ZZ%'
   AND b.ContCode = a.ProdCode
...
가만히 보니 저런식으로 되어 있었습니다.
a의 column은 출력안하고... 심지어 a와 b의 join 조건이 달랑 1개의 column인데 그마저 따로 조건이 있다보니
아에 a를 FROM에서 빼버리고
그냥 바로 b.ContCode LIKE 'ZZ%'로 하면 되겠구나 생각이 들었습니다.
이미 답안지를 엄청 작성한 뒤라서 다시 답안지를 받아서 작성했습니다. ㅠㅠ
서술형 2번은 UNION ALL을 이용하여 서로 다른 조건이 입력된 경우 나누어서 실행하는 방식의 문제였습니다.
Table 2개를 JOIN 하는데 위와 아래의 SELECT 문에서 a와 b의 JOIN 칼럼이 다릅니다.
대충 SQL문을 복기하자면 다음과 같은 모양입니다.
SELECT ...
  FROM a, b
 WHERE a.ContCode = b.ProdCode
   AND SUBSTR(a.dt,1,6) = SUBSTR(b.dt,1,6)
   AND b.id = :id
   AND b.ProdCode IS NOT NULL
   AND a.code IN (1,2,3,4,5,6)
UNION ALL
SELECT ...
  FROM a, b
 WHERE a.ContCode = b.UserCode
   AND SUBSTR(a.dt,1,6) = SUBSTR(b.dt,1,6)
   AND b.id = :id
   AND b.ProdCode IS NULL
   AND a.code IN (1,2,3,4,5,6)
  • a Table은 500만건
  • b Table은 5000만건
  • a.ContCode의 Cardinality가 10
  • b.ProdCode의 Cardinality가 50
  • a.code는 7개가 있으며 균등분포
위의 조건이었습니다. SELECT의 ... 부분이 엄청 길고 복잡해서 답안지 작성하는데 시껍했습니다. 욕나오더군요 ;;;
제가 작성한 답은 b의 INDEX로 b1 (id, ProdCode, dt) , b2 (id, UserCode, dt) 이렇게 2개를 추가하고,
a의 INDEX로 (ContCode, code)를 추가하여서 위 SQL에서는 b1과 a의 index를 아래에서는 b2와 a의 index를 사용했으며,
AND b.dt LIKE SUBSTR(a.dt,1,6) || '%'
로 비교를 하였습니다.
처음 생각에는 a.code 를 NOT IN 으로 고칠까 생각했는데... 그렇게 하면 INDEX를 사용못하기 때문에 저건 함정일꺼라 생각하고 그냥 두었습니다.
객관식 및 단답형은 솔직히 책을 2번 읽은게 다이고, 별도로 뭔가를 외운다던지 그러지 않아서 ㅠㅠ
모르겠는건 그냥 깔끔하게 가장 그럴듯한걸로 찍고... 빨리 빨리 넘어 갔습니다. 단답형 중 대충 기억나는 문제는 다음과 같습니다.
  • SELECT ... Grouping(컬럼) 을 넣어두고 4군데 답적는거 : 저는 1 1 1 0으로 적었습니다. (각 컬럼별 합계에는 1, 최종 전체 합계는 0)
  • 윈도우 함수로 각 deptno별 2칸 앞에 sal을 출력하는건데 alias가 LEAD였습니다. : 정답은 LAG(sal,2,0) 으로 추정됩니다.
  • deptno, job 별로 9개의 소개가 나오고 전체 합계가 나오는 문제 : 저는 ROLLUP ((deptno,job)) 라 적었습니다.
  • Natural Join 설명해주고 적는거
  • CONNET BY PRIOR ... 적는거
  • UNION 으로 적은 SQL과 같은 기능을 하는 SQL을 UNION으로 한걸 inline view로 해서 밖의 SQL의 SELECT ( ) * 에서 괄호안에 들어가는거 : DISTINCT
  • CBO의 3가지 구성에서 질의변환기, 대안 계획 생성기 ( ) : 정답은 비용예측기 인듯한데... 전 비용계산기라 적었습니다. ㅠㅠ
  • REVOKE 적는 문제
등이 있었구요. 객관식 중에서는 기억나는게
  • Redo Log의 기능이 아닌것은 ?
  • sum() 함수에 null이 들어간 경우에 대한 문제 : 정답은 sum(c1) + sum(c2) 인듯...
정도네요.
결과는... 1달 후를 기다려 봐야 알것 같습니다.

2016년 2월 21일 일요일

Oracle Plan, Trace 읽는 법

Oracle Plan, Trace 읽는 법

SQL Tuning을 하기 위해서 가장 기본으로 알아야 하는 것이 Plan과 Trce를 읽는 방법입니다.
그래야 어느 곳이 비효율적인지를 알아내서 그 부분을 중심으로 Tuning 전략을 세울 수 있습니다.
아래 내용중 SELECT Tuning시 중요하게 봐야할 사항은 다음과 같습니다.
  • 실행 순서 : Plan, Trace 동일
  • Trace 결과 : Row Source Operation의 각 수치들의 의미 (rows, cr만 알아도 됩니다.)

1. Plan 읽는 법

  • Plan은 SQL을 실행하기 전에 Optimizer에 의해 선택된 최적의 실행 경로 및 계산되어진 예상 Cost를 보여줍니다.
*************************[Explain Plan Time: 2016/02/21 14:01:15]*************************
Execution Plan
-----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=5 Card=5 Bytes=325)
   1    0   SORT (ORDER BY) (Cost=9 Card=5 Bytes=325)
   2    1     UNION-ALL
   3    2       COUNT (STOPKEY)
   4    3         VIEW (Cost=5 Card=1 Bytes=65)
   5    4           SORT (ORDER BY STOPKEY) (Card=1 Bytes=14)
   6    5             FILTER
   7    6               TABLE ACCESS (FULL) OF 'BBS' (TABLE) (Cost=3 Card=10 Bytes=140)
   8    2       VIEW (Cost=4 Card=4 Bytes=260)
   9    8         SORT (ORDER BY) (Cost=4 Card=4 Bytes=56)
  10    9           COUNT (STOPKEY)
  11   10             TABLE ACCESS (FULL) OF 'BBS' (TABLE) (Cost=3 Card=5 Bytes=70)
-----------------------------------------------------------

Predicate information (identified by operation id):
-----------------------------------------------------------
   3 - filter(ROWNUM<=4)
   5 - filter(ROWNUM<=4)
   6 - filter(NULL IS NOT NULL)
   7 - filter("NUM"<10)
  10 - filter(ROWNUM<=4)
  11 - filter("NUM">10)
-----------------------------------------------------------

1.1 실행순서 (access path)

  • sibling 사이에서는 먼저 나온 것을 먼저 처리
  • child가 있는 경우 child부터 다 처리하고 parent 처리하기
이 두가지만 기억하면 됩니다.
위 Plan을 기준으로 처리 순서는 다음과 같습니다.
(0 ~ 11까지 있는 왼쪽의 Index를 사용하겠습니다.)
7 -> 6 -> 5 -> 4 -> 3 -> 11 -> 10 -> 9 -> 8 -> 2 -> 1 -> 0
  • (4) UNION-ALL 아래에 2개의 child(3,8)가 있습니다.
  • 이 둘중 위에 있는 (3)부터 처리를 해야하는데 (3)은 child가 있으므로 가장 안쪽부터 처리합니다.
  • (3)의 child를 다 처리한 후에 자신의 sibling인 (8)을 처리해야하는데, (8)도 child가 있으므로 안쪽부터 처리합니다.
  • (3, 8)이 모두 처리된 후에 (2)부터 쭉 처리하면 됩니다.

1.2 예상 성능지표 (Cost-based Optimizer Mode에서만 표시)

  • Cost : Cost 예상 지수. 클수록 성능상 (CPU 점유, Disk I/O, 수행시간 등...) 안좋다는 의미입니다.
  • Card : (Computed Cardinality) : CBO상 계산된 예상되는 return row 입니다.
  • Bytes : return row의 byte수 입니다.

1.3 Predicate information

각 단계별 filter 조건이 어떻게 적용되었다는 정보를 보여줍니다.

2. Trace 읽는 법

  • Trace는 실제 실행된 경로와 그 성능상 중요 수치들을 보여줍니다.
Compile Time  : 2015/07/09 13:31:22
Trace File    : c:\oracle\diag\rdbms\orcl\orcl\trace\orcl_ora_11048.trc
Trace Version : 11.2.0.1.0
********************************************************************************

SELECT * FROM SCOTT.EMP
 WHERE DEPTNO = :"SYS_B_0"

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.001          0          0          0          0
Fetch        1    0.000        0.000          0          3          0          0
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total        3    0.000        0.001          0          3          0          0

Misses in library cache during parse   : 1
Optimizer Goal : ALL_ROWS
Parsing user : SYS (ID=0)


Rows     Row Source Operation
-------  -----------------------------------------------------------------------
      0  TABLE ACCESS FULL EMP (cr=3 pr=0 pw=0 time=0 us cost=2 size=190 card=5

2.1 Row Source Operation 읽는법

상대적으로 중요한 Row Source Operation 읽는 법부터 소개해드리겠습니다.
Plan과 같은 형식으로 실행 경로를 보여 줍니다.
읽는 법은 Plan과 같으며 괄호 안에 나오는 성능지표 값을 해석하는 것이 중요합니다.
  • Rows (왼쪽) : return row 수 입니다. 해당 단계에서 몇건의 row가 결과로 return 되었는지 알려줍니다.
  • cr : (Consistent Mode Block Read) 총 읽은 block수 입니다. 의미상은 DB Buffer Cache에서 읽은 block수 이지만, disk상에서 읽은 경우에도 buffer로 먼저 올린 후에 읽어야 하므로 사실상 disk + cache에서 읽은 총 수라고 해석하면 됩니다.
  • pr : (Physical Disk Block Read) disk에서 읽은 block수 입니다.
  • pw : (Physical Disk Block Write) disk에 저장한 block수 입니다.
  • time : 소요시간 (microsecond 단위)
  • cost : cost (성능상)
  • size : data size
  • card : (cardinality)

2.2 Call Table

Tunning시 사실상 크게 볼 필요 없습니다.
  • Call
    • Parse : Cursor를 Parsing하고 Execution Plan을 생성하는 단계
    • Execute : Cursor를 실행하는 단계
    • Fetch : 결과 Record를 Fetch하는 단계
  • Count : 수행 회수
  • CPU : CPU 사용시간
  • Elapsed : 수행시간 ( CPU time + Wait time )
  • Disk : Disk에서 읽은 Block수
  • Query : Consistent Mode에서 읽은 Block수 (Query 수행 시점에 읽은 읽기 전용 Block)
  • Current : Current Mode에서 읽은 Block수 (Table을 액세스하는 시점에 읽은 수정할 Block)
  • Rows : 읽거나 갱신한 처리 건수

참조 Slide

좀 더 자세한 사항을 알고 싶으시면 아래 Slide를 참고해주세요.


2016년 2월 12일 금요일

SQLP 요점정리 #20 : 3과목 Tuning - 5장 고급 SQL Tuning - 4절 Partition 활용, 5절 Batch Program Tuning

3과목 SQL 고급 활용 및 Tuning

5장 고급 SQL Tuning

5.4 Partition 활용

  • Partitioning 이란 ?
    • Table, Index를 Partition 단위로 나누어 저장
    • Partition Key에 따라 물리적으로 별도의 Segment에 저장
  • Partition 장점
    • 관리적 측면 : Partition 단위 백업, 추가, 삭제, 변경이 편리
    • 성능적 측면 : Partition 단위로 Query, DML이 수행되어서 Transaction 경합 및 부하 분산

5.4.1 Partition 유형

1. Range Partition
  • Partition Key 값의 범위(Range)로 분할
  • 가장 일반적인 형태
e.g. 날짜 칼럼 기준으로 판매데이터를 월별로 분할
CREATE TABLE 주문
(
    ...
)
PARTITION BY RANGE(주문일자)
(
    PARTITION P2009_Q1 VALUES LESS THAN ('20090401'),
    PARTITION P2009_Q2 VALUES LESS THAN ('20090701'),
    ...
    PARTITION P9999_MX VALUES LESS THAN (MAXVALUE)
)'
2. Hash Partition
  • Partition Key 값의 Hash 함수를 적용하여 그 값으로 Mapping
  • 고르게 분산되는 대신 각 Row의 저장위치 예측이 불가
  • 병렬처리 시 성능효과 극대화
  • DML 경합 분산에 효과적
e.g. 고객번호, 주문일련번호
3. List Partition
  • 불연속적인 값의 목록을 각 Partition에 지정
e.g. 판매 데이터를 지역별로 분할
4. Composite Partition
  • 2개 이상의 Partition 구성 (단, 맨 처음에 Hash가 올 순 없음)
  • Range나 List Partition에 Range, Hash, List를 Sub-partition으로 구성
e.g. Range + Hash로 구성
CREATE TABLE 주문
(
    ...
)
PARTITION BY RANGE(주문일자)
SUBPARTITION BY HASH(고객ID) SUBPARTITIONS 8
(
    PARTITION P2009_Q1 VALUES LESS THAN ('20090401'),
    PARTITION P2009_Q2 VALUES LESS THAN ('20090701'),
    ...
    PARTITION P9999_MX VALUES LESS THAN (MAXVALUE) 
);

5.4.2 Partition Pruning

  • Optimizer가 SQL의 대상 Table과 조건을 분석하여 불필요한 Partition을액세스 대상에서 제외하는 기능
  1. Static Partition Pruning
    • 액세스할 Partition을 Compile-Time에 미리 결정
    • 상수 조건으로 조회할 경우 작동
  2. Dynamic Partition Pruning
    • 액세스할 Partition을 Run-Time에 결정
    • Bind Variable로 조회하는 경우
    • NL Join시 Inner Table이 Join 칼럼 기준으로 Partition 되 있는 경우

5.4.3 Index Partitioning

  • Local vs Global
    • Local Partition Index
      • Table Partition과 1:1 대응하도록 Index Partitioning
      • Index Partition Key를 사용자가 따로 지정하지 않고, DBMS가 자동으로 관리
    • Global Partition Index
      • Table Partition과는 독립적으로 구성
  • Prefixed vs NonPrefixed
    • Prefixed Partition Index : Partition Key Column이 Index의 왼쪽 선두에 위치
    • NonPrefixed Partition Index : Partition Key Column이 Index의 왼쪽 선두에 있지 않거나, 아에 속하지 않을 경우
  • 위 조합중 Global NonPrefixed Partition Index는 Oracle에서 지원하지 않음
  • Index Partitioning Guide
    • NonPartitioned Index (일반 Index)
      • Partition Key Column이 조건절에 누락되면 여러 Index Partition을 액세스해야 하므로 비효율적
      • 특히 OLTP환경에서는 성능에 미치는 영향이 크므로 NonPartitioned 전략이 유용할 수 있음
      • NL Join에서 Partition Key에 대한 넓은 범위검색 조건을 가지고 Inner Table에 Partitioned Index로 액세스하면 비효율적 -> NonPartitioned Index 사용을 고려
      • Partition Index를 이용하면 SORT ORDER BY 대체 효과 상실 -> Sort 연산을 대체함으로 부분범위 처리를 활용하고자 할 경우 NonPartitioned Index가 유리함
      • Table Partition 이동,삭제 등 작업시 unsuable 되므로 적용 시 주의
    • Global Prefixed
      • Index 경합 분산에 효과적
      • 여러 Local Index Partition을 액세스하는 것이 비효율적일 경우 대안으로 활용
      • Table Partition 이동,삭제 등 작업시 unsuable 되므로 적용 시 주의
    • Local Prefixed
      • 관리적 측면에서 유용 : Table Partition에 대한 추가, 삭제 등의 작업이 빈번할 때
      • 이력성 데이터를 주로 관리하는 DB 환경에 효과적
      • Partition Key Column이 = 조건으로 사용될 때 유용
      • Partition Key Column에 대한 검색 조건이 없으면 정상적 사용이 불가 (Index Full Scan으로는 선택가능)
      • Partition Key Column이 범위검색 (LIKE, BETWEEN, 부등호) 일 경우 불리
    • Local NonPrefixed
      • Local Prefixed와 거의 같은 특징이긴하나
      • 범위검색이 주로 사용될 경우 NonPrefixed가 더 유리 (단, 좁은 범위검색이어야 함)

5.5 Batch Program Tuning

  • Batch Program이란 ?
    • User와의 상호작용(Interface)없이
    • 대량의 데이터를 처리하는
    • 일련의 작업들을 묶어
    • 정기적으로 반복 수행하거나 (정기 배치)
    • 정해진 규칙에 따라 (이벤트 배치)
    • 자동으로 수행 (수동으로 On-Demand 배치로도 수행가능)
  • Batch 환경의 변화
    • 과거 : 일, 월 단위로 주로 야간에 수행되었으며, Online과 Batch가 명확하게 구분되어서 사용되었지만,
    • 현재 : 시간, 분 단위의 짧은 시간에 수행되는 경우가 많으며 On-Demand Batch도 제한적이나마 허용되어야 한다.
  • 성능개선 목표 설정
    • 전체 Batch Program 들의 최종 수행시간 단축
      • Batch Window를 보고 Batch Program 간의 선후 관계를 따져가면서 전체적으로 고려
    • System 부하도 고려해야 함
      • 병렬도 (DOP : Degree of Parallelism)를 32로 하여 5분에 수행되는것보다는 병렬처리 없이 10분 소요되는게 더 나을 수 있다.
    • 경합을 최소화
      • CPU 자원 대량 사용 및 동일한 자원(데이터)에 접근하는 Batch Program을 분산
  • Batch Program 구현 Pattern과 Tuning 방안
    • 절차형으로 작성된 Program
      • Application Cursor를 열고, Loop 내에서 다른 SQL이나 Sub Procedure를 호출하면서 반복처리
      • (One SQL 보다) 구현이 쉽다.
      • 아무리 Tuning을 잘해도 다음과 같은 최적화 한계가 있음
        • 반복적인 DB Call 발생
        • Random I/O 위주
        • 동일한 데이터 중복 액세스
      • Tuning Guide
        • 병목을 일으키는 SQL을 찾아 I/O Tuning : Index 재구성 및 액세스 경로 최적화
        • Program Parallel 활용 : SQL이 읽는 데이터 범위를 달리하여 여러 Program이 동시에 수행
        • Array Processing 활용
        • One SQL로 다시 구현;;;
    • One SQL
      • One SQL로 구현하거나, 집합적으로 정의된 여러 SQL을 단계적으로 실행
      • 구현하기 어렵고, 업무가 복잡할 경우 여러 SQL들을 통합했다가 결과가 틀려질 수 있음
      • Tuning Guide
        • 병목을 일으키는 오퍼레이션을 찾아 I/O Tuning
          • Index Scan 대신 Full Table Scan으로
          • NL Join 보다 Hash Join으로
        • 임시 Table 활용
        • Partition 활용
        • 병렬처리 활용
  • 병렬 처리 활용
    • SELECT /*+ full(T) parallel(T, 4) */ ... : T Table을 Full Scan으로 4개로 병렬처리
    • SELECT /*+ index_ffs(T t_idx) parallel(T, t_idx, 4) */ ... : T Table의 t_idx Index를 Fast Full Scan으로 4개로 병렬처리
    • QC (Query Cordinator)
      • 병렬 SQL문을 발행한 Session
      • 병렬로 처리되지 않는 Table은 QC가 직접처리
      • 각 병렬 Server로부터의 산출물을 통합하는 작업 수행
      • 최종 결과 집합을 User에게 전송
    • Parallel Server Process
      • 병렬 SQL을 실제로 수행하는 개별 Session
    • Operation Parallelism
      • Intra-Opertarion Parallelism
        • 서로 배타적인 범위를 독립적으로 처리
        • 각각의 데이터를 Process별로 읽는 작업
        • 전달받은 데이터를 각각의 Process에서 처리
      • Inter-Operation Parallelism
        • 다른 서버 집합으로 분배하거나 정렬된 결과를 QC에게 전송하는 작업을 병렬로 동시에 진행
        • Process간의 통신이 발생