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

2009년 9월 1일 화요일

ORACLE_013. Understanding Access Path : Full Table Scans

Understanding Access Path : Full Table Scans                                          

FULL TABLE SCANS
 이 형식의 스캐닝 방식은 테이블에서 모든 자료를 읽어들인 후 필터를 통해 원하는 행을 얻어내는 방식 입니다. 풀 테이블 스캔이 일어나는 동안 하이워터마크(High Water Mark, HWM)밑에 있는 테이블 블록은 모두 읽혀집니다. 각각의 행은 구문의 where 절의 조건에 맞는지 확인됩니다.

 풀 테이블 스켄이 수행될때 오라클은 모든 블럭을 순차적으로 읽습니다. 이는 블럭들이 근접해 있으면, 하나의 블록을 읽어들이는 것 보다 더 많이 읽어드리기에 프로세스의 속도를 높일 수 있기 때문입니다. 한개의 블럭에서 여러개의 블럭을 읽어드리는 크기는 DB_FILE_MULTIBLOCK_COUNT 파라메터에 나타나 있습니다. 다중 블럭 읽기(multiblcok read)는 풀 테이블 스켄에서 매우 효율적 입니다. 각각의 블록은 단 한번만 읽힙니다.

WHY A FULL TABLE SCAN IS FASTER FOR ACCESSING LARGE AMOUNTS OF DATA
 풀 테이블 스켄은 테이블의 크고 조각난 블록에 접근할 경우 인덱스 범위 스켄(Index Range Scan)보다 비용이 더 싸게 먹힙니다. 풀 테이블 스켄은 큰 I/O 단위를 사용하는데 이는 작은 I/O를 여러번 호출하는 것 보다 비용이 싸기 때문이죠.

WHEN THE OPTIMIZER USES FULL TABLE SCAN
 다음의 경우에 수행합니다.

 Lack of Index
 질의(Query)가 존재하는 인덱스를 사용할 수 없으면, 풀 테이블 스켄을 수행합니다. 인덱싱된 컬럼에 펑션(function)을 사용할 경우 인덱스를 사용하지 않고 풀 테이블 스켄을 사용합니다.
  Example)
  SELECT last_name, first_name
  FROM   employees
  WHERE UPPER(last_name) LIKE :b1

  * 만약 케이스에 의존하는 검색을 수행할 경우 검색하는 컬럼에 대하여 케이스를 섞는것을 허용하지 말거나 펑션 기반의 인덱스, 예를들어 UPPER(last_name)를 만드는 것을 허용하지 마십시요. 좀더 자세한 정보를 원하시면 아래 접어놓은 내용을 참고 하세요. (영문)

 

Function-Based Index

 

 Large Amount of data
  만약 옵티마이저가 생각하기에 테이블의 대부분의 블럭을 읽어들인다 판단하면 인덱스가 존재한다 하더라도 풀 테이블 스켄을 수행합니다.

 Small Tables

  테이블의 하이워터마크 밑의 블럭이  DB_FILE_MULTIBLOCK_COUNT 에 정의되어 있는 값보다 적은 경우, 즉 단 한번의 I/O만으로 테이블을 전부 읽을 수 있는 경우 풀 테이블 스켄을 수행합니다. 이럴경우 인덱스가 존재한다고 하여도 풀 테이블 스켄을 수행합니다.

 

 High Degree of Parallelism

  고도(High Degree)의 테이블 Skew 데이터라면 옵티마이저는 풀 테이블 스켄을 수행합니다. ALL_TABLES에서 DEGREE 값을 확인할 수 있습니다.


FULL TABLE SCAN HINTS
 FULL(table_alias)를 이용하여 테이블 스켄을 강제로 할 수 있습니다.
 
 SELECT /*+ FULL(e) +/ employee_id, last_name
 FROM employees e
 WHERE last_name LIKE :b1;

ASSESSING I/O BLOCKS, NOT ROWS
 오라클은 I/O 단위로 블럭을 다룹니다. 그러므로 옵티마이저는 행의 갯수가 아닌 블럭의 사용률에 따라 풀 테이블을 할지 결정합니다. 이는 인덱스 클러스터링 값으로 불리워집니다. 하나의 블럭에 하나의 행만 존재할시 Row에 접근하는 것과 블록에 접근하는 것이 같은 소요비용이 소모됩니다.

 하지만 대부분의 테이블은 각각의 블록에 여러개의 행을 가지고 있습니다. 그러므로 여러개의 행들을 최소의 블록에 함께 클러스터링 하기를 바랍니다. 그렇지 않으면 많은 수의 블럭에 데이터들이 퍼져나갈 것 입니다.


HIGH WATER MARK(HWM) IN DBA_TABLES
 DDT(Data Dictionary Table)는 삽입된 행이 차지하고 있는 블록의 트랙을 가지고 있습니다. HWM은 풀 테이블 스켄시 끝점을 나타냅니다. HWM은 DBA_TABLES의 BLOCKS에 저장되어 있습니다. 이 값은 테이블이 truncated 혹은 drop 될시 초기화 됩니다.

 예로 과거에 많은 행을 가지고 있던 테이블이 있었다고 가정해 봅시다. 대부분의 행이 최근에 지워졌습니다. 그래서 지금은 HWM 밑의 많은 블럭들이 빈 상태입니다. 이때 풀 테이블 스켄을 수행시 HWM까지 읽어드리기 때문에 좋지 못한 성능을 내게 됩니다.

ROWID SCANS

 각 행의 ROWID는 데이터 파일에 지정되어 있으며 데이터 블록은 행과 그 행위 위치한 정보를 포함하고 있습니다. ROWID 에 의해 위치가 지정된 행은 한개의 행을 가져오는데 가장 빠른 방법입니다.

 ROWID를 이용해 TABLE에 접근하려면 오라클은 우선 WHERE 구문 혹은 하나이상 테이블 인덱스를 통해 선택된 행에 대해서 ROWID를 획득합니다. 그리고 그 행의 ROWID를 이용하여 테이블에 각각 위치시킵니다.

WHEN THE OPTIMIZER USES ROWIDS
 일반적으로 인덱스에서 ROWID를 얻어낸 후의 다음 단계입니다. 인덱스가 존재하지 않는 컬럼에 대해서도 테이블에 대한 접근이 일어날 수 있습니다. ROWID를 이용한 접근방법은 다음에 나올 인덱스 스켄이 필요하지 않습니다. 구문에 사용되는 컬럼이 모두 인덱스가 있다면 ROWID를 이용한 접근은 일어나지 않을 것 입니다.

 

FIN
REF) Oracle Documents (Server .920)/a96533 "Introduction to the Optimizer"

2009년 8월 26일 수요일

ORACLE_010. OPTIMIZER - Choosing Optimizer Approach and Goal

OPTIMIZER - Choosing Optimizer Approach and Goal                        

 기본적으로 CBO의 목표는 최상의 출력결과 입니다. 이는 최소한의 자원을 이용하여 쿼리를 수행하는데 필요한 행을 읽어들이는 방법을 선택하는 것 입니다. 또한 오라클은 반응시간의 최소화를 위한 최적화도 수행합니다. 반응시간이 뜻하는 바는 SQL 구문에 의해 최소의 자원을 이용하여 첫번째 행에 접근하는 방법 입니다.

 

 옵티마이저에 의해 생성된 실행계획은 옵티마이저의 목표에 따라 다양하기도 합니다. 많은 처리량을 위한 최적화는 인덱스 스켄보다 오히려 풀 테이블 스켄이거나 Nested Loop Join 보다 Sort Merge Join 일 수 있습니다. 최상의 반응시간을 위한 최적화는 Index Scan, 혹은 Nested Loop Join 입니다.

 

 예를들어, Sort-Merge 나 Nested Loop 중 하나를 사용하여 Join 구문을 수행한다고 가정해 봅시다. Sort-merge 방식은 아마도 Query 의 모든 결과를 뱉어내는데 빠를 것이고 Nested Loop 방식은 첫번째 행을 뱉어네는데 효율적일 것 입니다. 많은 처리량에 대한 향상이 목표라면 Sort merge join 을 사용하면 될 것 입니다. 반면 좀더 빠른 반응을 원한다면, 옵티마이저는 Nested loop join 을 사용하는게 좋을 것 입니다.

 

  - Oracle Reports Application 과 같은 어플리케이션이 Batch로 동작할때는 처리량에 관해 최적화를 합니다. Batch Application 에서의 처리량은 굉장히 중요한데 사용자는 어플리케이션이 끝마치는 시간이 얼만큼 필요할지만 고려하기 때문입니다. 반응시간은 좀 덜 중요한데, 어플리케이션이 수행되는 동안 개별적으로 실행된 구문의 결과를 계산하지 않기 때문입니다.

 

 - Interactive Applicatoin (대화형 어플리케이션), 예를들어 Oracle Forms App. 나 SQL*Plus 쿼리등은 반응시간에 촛점을 맞춥니다. 사용자들은 구문을 통해 첫번째 행이나 혹은 첫 몇개의 행을 눈으로 확인하기 위해 기다리기 때문입니다.

 

 옵티마이저는 다음과 같은 SQL 문의 요소로 데이터로의 접근과 목표를 최적화 합니다.

  - OPTIMIZER MODE Initialization Parameter

  - CBO Statistics in the Data Dictionary

  - Optimizer SQL Hints for Changing the CBO Goal

OPTIMIZER_MODE INITIALIZATION PARAMETER
 OPTIMIZER_MODE 초기화 파라미터는 인스턴스에서 옵티마이저가 선택할 기본 행동 방법을 설정합니다.

 

Value          Description            

CHOOSE    

 

 

 

 

 

 

 

 

ALL_ROWS

 

 

FIRST_ROWS_n 

 

 

FIRST_ROWS  

 

RULE

 옵티마이저는 Cost-base와 Rule-base중 하나를 선택합니다. 이는 Statistics 가 유효한지에서 결정됩니다.

 

  - DD(Data Dictionary)가 최소 하나의 테이블에 유효한 통계를 가지고 있다면 옵티마이저는 Cost-Based 방식을 사용합니다.

  - DD에 아주 소량의 통계만 있다면 그 값이 유효할때까진 Cost-base 를 사용합니다. 하지만 옵티마이저가 반드시 다른 통계 없이 이 구문을 수행하기 위한 통계를 추측합니다. 이는 차선책의 실행계획을 수행할 수 있습니다.

  - DD에 통계가 전혀 전재하지 않다면 Rule-base 방식을 사용합니다.

 

 통계의 존재 유무를 떠나서 세션의 모든 SQL문에 Cost-base 방식을 사용합니다. 많은 작업량 처리에 적합한 최적화를 실행합니다.(최소의 자원으로 모든 구문을 해결합니다.)

 

 통계의 유무에 상관없이 Cost-base 를 선택합니다. 또한 첫 n 개의 행을 뱉어내기 위해 최소의 시간을 소요하는 최적화를 수행합니다. n값은 1,10,100 혹은 1000 입니다.

 

 옵티마이저는 COST를 섞어 스스로 첫번째 행을 뱉어네는데 가장 좋은 계획을 결정해 냅니다.

 

 RULE-BASE 방식으로 설정합니다. 통계자료의 유무는 고려대상이 아닙니다.

 

 옵티마이저의 파라메터는 다음과 같은 방법으로 변경할 수 있습니다.

 

  ALTER SESSION SET OPTIMIZER_MODE = FIRST_ROWS_1;

 

OPTIMIZER SQL HINTS FOR CHANGING THE CBO GOAL
 개별적으로 수행하는 SQL 문의 CBO 를 변경하기 위해서 다음의 힌트를 개별 SQL에 삽입할 수 있습니다.

 - FIRST_ROWS(n),   n은 어떤 양수도 가능합니다.

 - FIRST_ROWS

 - ALL-ROWS

 - CHOOSE

 - RULE

 

CBO STATISTICS IN THE DATA DICTIONARY

 CBO가 사용하는 통계정보는 DD(Data Dictionary)에 저장되어 있습니다. DBMS_STATS 패키지나 ANALYZE 구문을 통해 물리적 저장장치의 특성이나 스키마 오브젝트의 데이터 분산정도를 수집할 수 있습니다.

 

       * ORACLE은 ANALYZE 구문보다 DBMS_STATS 패키지를 이용하여 통계정보를 모으는 것을

       권장합니다. 이 패키지는 통계정보를 병렬로 수집 가능하게 해 주며 파티션된 오브젝트의 정보

       를 모을 수 있습니다. 또한 다른 여러가지 방법으로 통계정보를 모을 수 있는 수단을 제공합니

       다. 게다가 CBO 는 DBMS_STATS를 이용해 수집한 통계정보만을 사용할 것 입니다.

 

       하지만 DBMS_STATS 보다 ANALYZE를 반드시 사용해야 할 경우가 있습니다.

        - VALIDATE 혹은 LIST CHAINED ROWS 단서를 달아 사용할때

        - FREELIST BLOCKS 의 정보를 수집할 때

 보다 효과적으로 CBO를 사용하기 위해 존재하는 데이터들의 통계정보를 가지고 있어야 합니다. SKEW DATA라 불리우는 중복되는 넓은 범위의 숫자로 이루어진 컬럼이 있다면 히스토그램 정보를 모으길 권장합니다.

 

 통계정보의 결과는 CBO에게 데이터의 유일함과 분산정도의 정보를 제공합니다. 이 정보를 이용하여 CBO는 높은 수준의 정확한 실행계획의 비용을 계산할 수 있습니다. 이는 CBO가 가장 적은 비용을 소요하여 실행 계획을 선택하는 것을 가능하게 해 줍니다.

FIN
REF) Oracle Documents (Server .920)/a96533 "Introduction to the Optimizer"

 

Next => Understanding the Cost-Based Optimizer

 

ORACLE_009. OPTIMIZER - OVERVIEW

OPTIMIZER - OVERVIEW                                                                    

OVERVIEW SQL PROCESSING
 SQL 프로세싱은 SQL문을 실행하기 위해 다음과 같은 절차를 따릅니다.

 - 분석자(PARSER)는 SQL문을 분석합니다. (PARSING)

 - 옵티마이저는 비용기반의 옵티마이저 (COST BASED OPTIMIZER, CBO) 혹은 규칙기반의 옵티마이저 (RULE-BASED OPTIMIZER, RBO)중 최고의 효율을 보여주는 방법중 하나를 선택합니다.

 - RSG(Row Source Generator)는 옵티마이저에게 최적화된 계획을 받고 SQL 실행을 위한 최적화된 실행 계획을 출력합니다.

 - SQL 실행 엔진(SQL Execution Engine)은 SQL문을 실행계획에 따라 실행하고 쿼리의 결과를 생산합니다.

<Picture : SQL Processing Overview : www.oracle.com>

OVERVIEW OF THE OPTIMIZER
 옵티마이저는 SQL 문에 있는 특정한 조건과 참조되는 오브젝트들에 대한 요소들을 분석하고 SQL 문을 가장 효율적으로 수행할 수 있는 방법을 선택합니다. 이러한 선택은 SQL을 실행하는 과정에서 굉장히 중요한 부분이며, SQL을 실항하는 시간에 지대한 영향을 끼칩니다.

 

 SQL은 다음과 같은 여러가지 방법으로 수행될 수 있습니다.

 

 - Full table scans

 - Index scans

 - Nested loops

 - Hash joins

 

 옵티마저에서 생성한 출력물은 쿼리 수행에 있어 가장 최적화된 방법을 설명합니다. 오라클 서버는 비용기반(Cost-based)과 규칙기반(Rule-based)의 최적화 방식을 제공합니다. 일반적으로 최종 목표 데이터에 접근하는데는 비용기반 방식이 사용됩니다.

 

 사용자는 옵티마이저를 세팅하거나 STATISTICS를 수집하여 데이터에 접근하는 방법을 조절할 수 있습니다.

 떄떄로 어플리케이션의 데이터에 대한 충분한 정보를 가지고 있는 어플리케이션 디자이너들은 SQL 문을 수행하는데 좀더 효과적인 경로를 직접 선택할 수 있습니다. 어플리케이션 디자이너는 SQL 문에 HINT 절을 이용하여 그 SQL문이 수행하는데 필요한 정보를 제공할 수 있습니다.

 

FEATURES THAT REQUIRE THE CBO
 다음은 CBO(Cost-Base Optimze)를 수행하는데 필요한 조건들 입니다.

 - Partitioned Table and Index
 - IOT (Index Organized Table)

 - Reverse Key Index

 - Function-based Index

 - SAMPLE clause in a SELECT statement

 - Parallel query and parallel DML

 - Star transformations and star joins

 - Extensible Optimizer

 - Query rewirte with materialized views

 - Enterprise Manager progress meter

 - Hash Joins

 - Bitmap indexes and bitmap join indexes

 - Index skip scans

 OPTIMIZER_MODE 가 RULE로 되어 있다고 해도 위 사항중 하나라도 해당이 되면 CBO로 실행이 됩니다.

OPTIMIZER OPERATIONS
 오라클에 의해 수행되는 모든 SQL문은 옵티마이저에 의해 다음을 수행 합니다.  


  Evaluation of expressions and conditions

      옵티마이저는 첫째로 가능한한 모든 조건들과 값들을 평가합니다.
  Statements transformation
      복잡한 구문을 포함한 쿼리 - 서브쿼리 혹은 뷰 (예) -  들은 Join 을 이용한 구문으로 변환합니다.
  Choice of optimizer approches
      옵티마이저는 CBO와 RBO 중 하나를 선택하고 최적화 목표를 결정합니다.
  Choice of access path
      옵티마이저는 테이블 데이터를 얻기 위한 하나 혹은 그 이상의 접근 경로를 결정합니다.
  Choice of join orders
      두 테이블 이상이 결합된 Join 문에서 옵티마이저는 우선 몇개의 테이블을 Join 될 지결정하고,

      결과에 몇개의 테이블이 Join 될 지를 결정합니다.

  Choice of join methods
      어던 구문에서도 Join을 수행하기 위한 동작을 결정합니다.


       
 

FIN
REF) Oracle Documents (Server .920)/a96533 "Introduction to the Optimizer"

2009년 8월 25일 화요일

ORACLE_008. ABOUT LATCH

ABOUT LATCH                                                                                      

LATCH 가 뭐죠?

 LATCH는 매우 간단합니다. SGA에 있는 공유 데이터가 보호될 수 있게 해주는 저레벨의 메커니즘입니다 (- _-;; 이게 간단해?). 예를 들어 사용자가 현제 DATABASE 에서 읽고 있는 데이터의 리스트를 보호하고 버퍼케시 블록에 있는 데이터의 구조를 변형되지 않게 보호하는 것 입니다.

 서버 프로세스나 백그라운드 프로세스가 자료를 변경하거나 조회를 하기 위해서는 반드시 LATCH와 함께 동반해야 하고, 작업이 끝나면 반드시 LATCH를 풀어주어야 합니다.

 

TUNING LATCHES

 LATCH는 튜닝할 필요가 없습니다(..;). LATCH에 대한 경합(CONTENTION)이 일어나게 된다면 이는 SGA에서 잘못된 리소스 사용이 일어났기 때문입니다. V$LATCH 를 조회하는 것은 문제를 해결하는데 도움이 되지 않습니다.

 

WAITING LATCH

 LATCH는 일반적으로 0 값을 가진채로 메모리 한 구석에 박혀있습니다. 만약 LATCH가 0이 아닌 값을 갖게 된다면 이 LATCH는 다른 PROCESS가 납치해 간 것 입니다.

 

 하나의 CPU를 사용하는 환경에서, LATCH를 다른 프로세스가 사용하고 있다면 뒤늦게 LATCH를 요청한 프로세스는 SLEEP 상태로 접어들게 됩니다.

 

 여러개의 CPU 환경하에서는 LATCH를 다른 프로세스가 사용하고 있다면 뒤늦게 LATCH를 요청한 프로세스는 일정 횟수만큼 스핀 상태(할일없이 뱅뱅 노는거죠.)를 지나 다시 LATCH를 획득하기 위해 요청을 합니다. 그런데도 LATCH를 획득할 수 없으면 다시 스핀 상태로 돌아갑니다. 이러한 스핀상태가 여러번 지속된 후에도 LATCH를 획득할 수 없으면 그 프로세스는 SLEEP 상태로 빠저들고 말죠. 이러한 SPIN TIME은 플랫폼이나 O/S가 결정합니다.

 

LATCH REQUEST

 LATCH를 요청하는 두가지 방법중 한가지 방법을 이용해 이를 획득합니다.

 

 WILLING-TO-WAIT

  WILLING-TO-WAIT 으로 요청했는데 LATCH가 사용하지 못한다면, 프로세스는 아주 잠시 대기한 후 다시한번 LATCH를 요청하게 됩니다. 프로세스는 LATCH를 사용할 수 있을때까지 요청과 대기를 계속해서 반복을 합니다. 이 방법은 가장 일반적인 방법입니다.

 

 IMMEDIATE

  IMMEDIATE를 이용한 LATCH 요청이 실패한다면 LATCH 획득시까지 기다리지 않고 다른 명령을 수행합니다. 예를들어 PMON(Process MONitor)이 비정상 종료된 프로세스를 청소하려 했으나 LATCH에 접근할 수 없는 상황이 발생했습니다. 그럼 PMON은 LATCH가 풀릴때까지 기다리지 않고 다음 명령을 수행하게 됩니다.

 

LATCH CONTENTION

 V$LATCH 뷰는 Willing-to-wait 형식의 요청이 GETS, MISSES, SLEEPS, WAIT_TIME, CWAIT_TIME, SPIN_GETS 의 컬럼으로 표현됩니다.  IMMEDIATE 형식의 요청은 IMMEDIATE_GETS, IMMEDIATE_MISSES로 표현됩니다.

 물론 우리의 만능 STATS 팩으로도 확인할 수 있습니다!!(야호!)

 

  GETS : Willing-to-wait 요청이 성공한 횟수

  MISSES : Willing-to-wait 요청이 실패한 횟수

  SLEEPS : Willing-to-wait 으로 기다리다 기다리다 지쳐 잠든 횟수

  WAIT_TIME : Willing-to-wait 으로 기다린 시간 (Milisecond)

  CWAIT_TIME : Spin Time 과 Sleep Time 을 합친 시간 입니다.

  SPIN_GETS : LATCH의 마음을 잡기 위해 붕붕 돌다가 결국 LATCH를 획득한 횟수 입니다.

  IMMEDIATE_GETS : 즉시 LATCH 요청에 성공한 횟수

  IMMEDIATE_MISSES : 즉시 LATCH 요청 실패한 횟수

 

REDUCING CONTENTION FOR LATCHES

 일반적으로, DBA는 LATCH를 튜닝할 필요가 없습니다. 허나 다음의 스텝들은 굉장히 유용합니다.

  - 좀더 자료를 수집하여 LATCH가 경합이 일어나는지 확인하십시요.

  - LATCH에 대한 경합이 SHARED POOL 이나 LIBRARY CAHCE에서 자주 일어나면 APPLICATION 튜닝을 고려해 보십시요.

  - 정보를 수집하여 SHARED POOL 과 BUFFER CACHE의 크기를 조정하십시요.

 

DBA에게 중요한 LATCH

 shared pool latch, and library cache latch :

  이곳에서 일어나는 LATCH의 경합은 SQL, PL/SQL 문이 재사용 되지 않기 때문에 일어납니다. 이러한 일이 일어나는 이유로는 변수가 BIND 되어 있지 않거나 커서(CURSOR) 캐시가 충분하지 않기 때문입니다. 문제를 해결하기 위해서 SHARED POOL을 튜닝하거나 APPLICATION을 튜닝해야 합니다.

 

 cache buffers lru chain latch :

  이곳에서는 더티 블락(dirty blocks)이 디스크에 쓰여질때나 서버 프로세스가 쓰기 위해 블럭을 검색할때 LATCH 가 필요합니다. 이곳에서 LATCH의 경합이 발생한다면 버퍼케시에 지나치게 많은 처리량이 늘어나거나 캐시에서 너무 많은 정렬기능 (Cache-based sort), 잘못된 인덱스의 반복적 (Large index range scans) 접근을 일으키는 SQL, 혹은 너무 많은 테이블 스켄이 일어나는 경우 입니다. 또한 DBWR(DATABASE WRITER)가 잦은 데이터 블록의 변화로 자신의 페이스(PACE)를 유지하지 못할경우와 빈 버퍼를 찾기위해 잡아놓은 LATCH의 시간보다 강제로 더 길게 FOREGORUND PROCESS가 WAIT 하면 발생할 수 있습니다. 이 문제를 극복하기 위해선 BUFFER CACHE와 DATABASE WRITER OPERATION을 튜닝할 것을 고려해 보십시요.

 

 cache buffers chain latch :

  이 Latch는 사용자 프로세스가 버퍼케시에 데이터 블락을 올려 놓을때 필요합니다. 이 Latch에 대한 경합이 일어나는 이유는 특정한 블럭(hot blocks)에 반복적으로 접근하고 있기 때문입니다.

 

FIN
REF) Oracle9i Performance Tunning - Volume I

 

다음편 예고!!)

 OPTIMIZER를 이용한 SQL TUNNING!! 상당히 포스트 연재가 길어질 것 같습니다. 내용이 좀 방대하군요.

ORACLE_008. MONITORING LOCK CONTENTION - Diagnostic

MONITORING LOCK CONTENTION - Diagnostic                              

DIAGNOSTIC

 DBA_WAITER & DBA_BLOCKER를 통해 누가 테이블을 홀딩하고 있고 누가 기다리고 있는지의 정보를 얻을 수 있습니다.  이 뷰를 이용하기 위해서는 CATBLOCK.SQL 을 수행해야 합니다.

            * $ORACLE_HOME/rdbms/admin 에서 찾을 수 있습니다.

 

      TRANSACTION 1

       UPDATE employee SET salary = salary * 1.1;

       //V$LOCK

      TRANSACTION 1

       UPDATE employees SET salary = 1.1;

       //V$LOCKED_OBJECT

 

V$LOCK VIEW

 LOCK TYPE        ID1

 TX                        롤백 세그먼트와 슬롯 번호

 TM                       바뀌기 시작한 테이블의 오브젝트 ID

 

 V$LOCK 뷰의 리소스 ID 1과 부합하는 테이블의 이름을 찾기위해 다음 쿼리를 이용합니다.

 

 SQL> SELECT owner, object_id, object_name, object_type, V$lock.type

    2>    FROM dba_objects, v$lock

    3>    WHERE object_id = v$lock.id1 and object_name = table_name;

 

V$LOCKED_OBJECT VIEW

 LOCK TYPE            ID1

 XIDUSN                  롤백 세그먼트 번호

 OBJECT_ID            변경되기 시작한 오브젝트의 ID

 SESSION_ID          오브젝트를 LOCK한 세션의 ID

 ORACLE_USERNAME

 LOCKED_MODE

 

 V$LOCKED_OBJECT 뷰에 있는 오브젝트 ID와 부합하는 테이블 이름을 찾기.

 

 SQL> SELECT xidusn, object_id, session_id, locked_mode,

    2>    FROM v$locked_object;

       XIDUSN   OBJECT_ID  SESSION_ID  LOCKED_MODE

      ------------   ----------------  ----------------- ------------------------

                    3                2711                       9                               3

                    0                2711                       7                               3

 

 SQL>SELECT object_name FROM dba_object WHERE object_id=2711;

      OBJECT_NAME

       ----------------------

       EMPLOYEE

 

 XIDUSN 의 값이 0이면 XIDUSN 의 값이 0이 아닌 다른 세션에 의해 걸린 LOCK이 WAIT 상태에 있는 세션을 뜻하게 됩니다.

 

UTLLOCKT SCRIPT

 $ORACLE_HOME/rdbms/admin/에 있는 utllockt.sql 스크립트를 이용하는 방법도 좋습니다. LOCK&WAIT 의 상태를 계층적으로 보여주기 때문에 가시적으로 확인하기가 더욱 쉽습니다. UTLLOCKT.SQL 스크립트를 수행하기 전에 CATBLOCK.SQL 스크립트를 SYS권한으로 우선 수행해야 합니다.

 

  WAITING_SESSION        TYPE       MODE  REQUESTED      MODE HELD      LOCK ID1   LOCK ID2

  ---------------------------    ------------  --------------------------------  ---------------------  ---------------- ---------------

  8                                       NONE      None                                    NONE                   0                    0

          9                               TX            Shares (S)                            Exclusive (X)         65547            16

                 7                        RW           Exclusive (X)                       S/ROW-X (SSX)   33554440      2

               10                        RW           Exclusive (X)                       S/ROW-X (SSX)   33554440      2

 

 위 예제에서 보듯이 9번 세션은 8 세션이 TRANSACTION이 끝나길 기다리고 있고 7,10번은 9번 세션을 기다리고 있습니다. (참 쉽죠잉~)

 

RESOVING CONTENTION

 세션을 죽이십쇼!(KILL!!). 그것이 유일한 방법 일 것 입니다. (TRX)가 끝나지 않는다면 말이죠. 이는 (DEAD-LOCK)에서도 마찬가지 입니다.

 

 ALTER SYSTEM KILL SESSION 'SID, SERIAL#';

 

 SID와 SERIAL#을 조회하는 방법입니다.

 

 SQL> SELECT SID, SERIAL# FROM V$SESSION WHERE TYPE='USER';

 

FIN.

REF)Oracle9i Performance Tuning Volume - I

ORACLE_007. MONITORING LOCK CONTENTION - Table Lock, DDL Lock

MONITORING LOCK CONTENTION - Table Lock, DDL Lock            

MANUAL TABLE LOCK MODES (SYNTAX)

 SQL> LOCK TABLE table_name IN mode_name MODE;

            *SQL>LOCK TABLE employee IN exculsive MODE;

 

MODE : SHARE (S) LOCK

 이 모드는 다른 TRANSACTION에게 오직 SELECT . . . FOR UPDATE 만 허용합니다. 당연히 테이블을 변환시키는 일련의 어떠한 행동도 막아버립니다.

 

MODE : SHARE ROW EXCLUSIVE (SRX) LOCK

 DML 명령이나 수동으로 SHARE LOCK 을 획득하는 어떠한 행위도 막아버리는 높은 수준의 테이블 락 입니다. 맹목적으로 데이터의 무결성 참조를 위해 사용합니다.

 

MODE : EXCLUSIVE (X) LOCK

 테이블에 대한 쿼리만 허용합니다. 어떠한 타입의 DML이나 수동 LOCK을 제한합니다.

 

 TRANSACTION 1          

TRANSACTION 2           

 LOCK TABLE  department IN                                              

 EXCLUSIVE MODE: 

 Table(s) Locked;

SELECT * FROM department                                  

FOR UPDATE;

Transaction 2 wait.

 

DDL LOCK

 EXCLUSIVE DDL LOCK은 DROP TABLE, ALTER TABLE 문에 필요합니다.

 CREATE, ALTER, DROP 같은 DDL 문은 적용할 오브젝트에 대해 반드시 EXCLUSIVE LOCK 이 필요합니다. 어떠한 레벨의 락이 걸려있다면 ALTER TABLE 구문은 실행되지 않습니다.

 

 TRANSACTION 1          

TRANSACTION 2           

 UPDATE employee  

 SET salary = salary*1.1                                                            

3120 rows updated.

ALTER TABLE employee

DISABLE PRIMARY KEY;

ORA-00054 : Resource busy and                          

acquire with NOWAIT specified

 

 SHARE DDL LOCK 은 CREATE PROCEDURE, AUDIT 문에 필요합니다.

 GRANT, CREATE PACKAGE는 Shared DDL Lock을 필요로 합니다. 이러한 종류의 락은 비슷한 DDL 구문을 제한하지 않습니다. 허나 참조하고 있는 오브젝트를 Altering 하거나 Dropping 하는 행위는 제한합니다.

 

fin.

REF) Oracle9i Performance Tuning - Volume I

2009년 8월 21일 금요일

ORACLE_003. STATS_PACK - GATHER - PART2

STATS_PACK - GATHER - PART 2                                                       

DBMS_STATS.GATHER_DATABASE_STATS (

   estimate_percent        

   block_sample  

   method_opt      
   degree

   granularity

   cascade  
   stattab          
   statid  

   options        OUT

   objlist        
   gather_sys

   no_invalidate

   gather_temp  

NUMBER

BOOLEAN

VARCHAR2

NUMBER

VARCHAR2          

BOOLEAN

VARCHAR2

VARCHAR2

VARCHAR2

ObjectTab,

VARCHAR2

BOOLEAN

BOOLEAN

BOOLEAN

DEFAULT NULL,

DEFAULT FALSE,

DEFAULT 'FOR ALL COLUMNS SIZE 1',

DEFAULT NULL,

DEFAULT 'DEFAULT',

DEFAULT FALSE,

DEFAULT NULL,

DEFAULT NULL,

DEFAULT 'GATHER',

 

DEFAULT NULL,

DEFAULT FALSE,

DEFAULT FALSE,

DEFAULT FALSE );

 

DBMS_STATS.GATHER_DATABASE_STATS (

   estimate_percent        

   block_sample  

   method_opt      
   degree

   granularity

   cascade  
   stattab          
   statid  

   options       

   statown

   gather_sys

   no_invalidate

   gather_temp  

NUMBER

BOOLEAN

VARCHAR2

NUMBER

VARCHAR2          

BOOLEAN

VARCHAR2

VARCHAR2

VARCHAR2

VARCHAR2

BOOLEAN

BOOLEAN

BOOLEAN

DEFAULT NULL,

DEFAULT FALSE,

DEFAULT 'FOR ALL COLUMNS SIZE 1',

DEFAULT NULL,

DEFAULT 'DEFAULT',

DEFAULT FALSE,

DEFAULT NULL,

DEFAULT NULL,

DEFAULT 'GATHER',

DEFAULT NULL,

DEFAULT FALSE,

DEFAULT FALSE,

DEFAULT FALSE );

 


    

DBMS_STATS.GATHER_SYSTEM_STATS (

   gathering_mod              

   interval

   stattab

   statid

   statown

VARCHAR2        

INTEGER

VARCHAR2

VARCHAR2

VARCHAR2         

 

DEFAULT 'NOWORKLOAD'                         

DEFAULT NULL,

DEFAULT NULL,

DEFAULT NULL

DEFAULT NULL );


           GATHERING_MODE

                GATHERING_MODE 의 값은 다음과 같습니다.

 

                NOWORKLOAD

                     시스템 활동을 캡춰하는데 워크로드가 필요하지 않습니다. 오라클 내부의 기본값을 이용해

                     시스템의 STATISTICS 를 생성합니다. 이 모드는 워크로드를 서브밋 할 수 없는 상황에 딱 알

                     맞는 옵션입니다 (예를들어, 개발 프로세스 중). 실제 작동중인 시스템의 활동에 기반한 시스템

                     STATISTICS 를 위해서는 INTERVAL 혹은 START | STOP 모드를 사용하십시요.

 

                INTERVAL

                     특정한 간격으로 시스템 활동을 캡춰합니다. 이 옵션은 INTERVAL 파라미터와 합쳐져 사용

                     합니다. 간격값은 분 단위 입니다. 시스템 STATISTICS 는 DICTIONARY 혹은 STATAB 에

                     생성됩니다. 정해진 스케쥴보다 일찍 수집활동을 멈추고 싶다면

                     EXEC DBMS_STATS.GATHER_SYSTAM_STATS(GATHERING_MODE=>'STOP') 구문을

                     이용하여 정지할 수 있습니다.

 

                START | STOP

                     원하는 시점에서 시스템 활동을 캡춰하고 DICTIONARY 혹은 STATTAB 에 정보를 업데이트

                     합니다. INTERVAL 값은 무시되어집니다. (당연하겠죠?)

 

          

     

        본문보다 더 쓸모있는 TIP! (본문은 그럼 뭐냐..) >

        전에 설명했던 값들의 설명은 제외하였고,  새로운 설정값에 관해서만 기술했습니다.

      GATHER_TABLE_STATS 의 STATTAB 과 GATHER_INDEX_STATS 의 STATTAB 은 그 사용법이

      동일합니다.

 

        기본적으로 STATS_PACK 을 사용하고 싶으면

 

                 SQL>EXEC DBMS_STATS.GATHER_[ TABLE | INDEX | DATABASE | SYSTEM]_STATS

                           (OWNNAME =>'VALUE', ESTIMATE_PERCENT=>'10', ... ) ;

 

      과 같이 사용하시면 됩니다.

        또한 일일이 REFERENCE 를 찾아볼 필요 없이 DESC[RIBE] 명령문을 통해 사용할 수 있는 방법을

      참고할 수 있습니다. DESC[RIBE]는 VIEW나 TABLE 등의 구성 정보만 보는 것이 아니라 이렇게 패키

      지의 정보도 확인할 수 있습니다.

 

      STATS_PACK.FINISH_GATHER_OPTIONS___________________________________________________