[오라클]2-2단계 Redo 로그 파일
|
'01.DB튜닝 > 006.단계별 서버 튜닝' 카테고리의 다른 글
[오라클]3-3단계 Lock의 경합 (0) | 2012.12.19 |
---|---|
[오라클]3-2단계 Temp 세그먼트 (0) | 2012.12.19 |
[오라클]3-1단계 Undo 세그먼트 (0) | 2012.12.19 |
[오라클]2-3단계 아카이브 파일 (0) | 2012.12.19 |
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
|
[오라클]3-3단계 Lock의 경합 (0) | 2012.12.19 |
---|---|
[오라클]3-2단계 Temp 세그먼트 (0) | 2012.12.19 |
[오라클]3-1단계 Undo 세그먼트 (0) | 2012.12.19 |
[오라클]2-3단계 아카이브 파일 (0) | 2012.12.19 |
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
|
[오라클]2-2단계 Redo 로그 파일 (0) | 2012.12.19 |
---|---|
[오라클]3-2단계 Temp 세그먼트 (0) | 2012.12.19 |
[오라클]3-1단계 Undo 세그먼트 (0) | 2012.12.19 |
[오라클]2-3단계 아카이브 파일 (0) | 2012.12.19 |
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
|
[오라클]2-2단계 Redo 로그 파일 (0) | 2012.12.19 |
---|---|
[오라클]3-3단계 Lock의 경합 (0) | 2012.12.19 |
[오라클]3-1단계 Undo 세그먼트 (0) | 2012.12.19 |
[오라클]2-3단계 아카이브 파일 (0) | 2012.12.19 |
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
|
[오라클]3-3단계 Lock의 경합 (0) | 2012.12.19 |
---|---|
[오라클]3-2단계 Temp 세그먼트 (0) | 2012.12.19 |
[오라클]2-3단계 아카이브 파일 (0) | 2012.12.19 |
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
[오라클]1-5단계 래치와 경합 (0) | 2012.12.19 |
|
[오라클]3-2단계 Temp 세그먼트 (0) | 2012.12.19 |
---|---|
[오라클]3-1단계 Undo 세그먼트 (0) | 2012.12.19 |
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
[오라클]1-5단계 래치와 경합 (0) | 2012.12.19 |
[오라클]1-4단계 자바풀 영역 (0) | 2012.12.19 |
디스크의 I/O 경합 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
먼저, 위치 이동을 하고자 하는 데이터 파일의 테이블스페이스를 OFFLINE 하십시오. SQL > CONNECT system/manager SQL > ALTER TABLESPACE sample OFFLINE; 이동하고자 하는 sample 테이터 파일을 이동하려는 경로로 복사합니다.(SAMPLE 데이터파일은 오라클9i를 설치하면 기본적으로 설치됩니다. 해당 경로에서 다음 작업을 하십시오) $ cp $HOME/dbs/sample01.dbf $HOME/disk4/sample01.dbf 다음과 같이 SAMPLE 데이터 파일의 경로를 RENAME 하십시오. SQL > ALTER TABLESPACE sample RENAME DATAFILE '$HOME/dbs/sample01.dbf' TO '$HOME/disk4/sample01.dbf'; RENAME 작업이 완료되었으면 엑세스가 가능하도록 해당 TABLESPACE를 ONLINE해 주십시오 SQL > ALTER TABLESPACE sample ONLINE; 정상적으로 자료입력이 되는지 확인 한 다음 O/S상의 OLD 파일은 삭제하십시오. SQL > ! rm /oracle/app/product/910/oradata/disk2/sample01.dbf SQL > EXIT 데이터 파일을 재배치 하는 방법은 두 가지가 있습니다. 첫 번째 방법은 데이터베이스를 종료한 후 마운트 상태로 구동하여 RENAME 하는 방법이며, 주로 SYSTEM 데이터 파일을 RENAME할 때 사용됩니다. 이유는, 오라클 데이터베이스의 필수 데이터 파일이기 때문입니다. 즉, 데이터베이스가 구동되려면 반드시 SYSTEM 데이터 파일은 사용가능 상태이어야 하기 때문에 마운트 상태에서 만 RENAME할 수 있습니다. 두 번째 방법은 데이터베이스를 오픈 상태에서 사용하고 있는 동안 특정 데이블스페이스를 RENAME하는 방법입니다. 주로 NON-SYSTEM 데이터 파일을 RENAME할 때 사용합니다. |
[오라클]3-1단계 Undo 세그먼트 (0) | 2012.12.19 |
---|---|
[오라클]2-3단계 아카이브 파일 (0) | 2012.12.19 |
[오라클]1-5단계 래치와 경합 (0) | 2012.12.19 |
[오라클]1-4단계 자바풀 영역 (0) | 2012.12.19 |
[오라클]1-3단계 로그버퍼 영역 (0) | 2012.12.19 |
LRU 알고리즘 먼저, 데이터베이스의 구조에는 데이터베이스 만을 위한 메모리 영역으로 SGA 영역(데이터버퍼 캐시, 로그버퍼, 공유 풀, 라지 풀 영역)이 있으며 또한 2개의 리스트(LRU-LIST, DIRTY-LIST)가 있습니다. LRU-LIST에는 데이터버퍼 캐시영역의 각 블록구조에 대한 사용 상태정보가 저장되어 있고 DIRTY-LIST에는 사용자에 의해 이미 트랜잭션이 완료된 블록에 대한 상태정보가 저장되어 있습니다.
먼저, LRU 알고리즘이 필요한 이유는 공유 풀 영역은 메모리 영역이기 때문에 그 크기가 항상 제한되어 있으며 항상 여유롭게 사용되지 못하는 물리적 한계를 가지고 있기 때문입니다.
자~ 그럼 LRU 알고리즘의 구체적 실행방법을 알아봅시다.
하나의 사용자가 데이터베이스에 접속하면 사용자 프로세스와 서버 프로세스가 할당됩니다. 사용자가 SQL문을 실행하면 서버 프로세스는 구문분석을 끝낸 후 실행(EXECUTE)작업을 하게되는데 먼저, 데이터버퍼 캐시영역을 검색해서 현재 실행된 SQL문에 있는 테이블이 다른 사용자에 의해 이미 읽혀져서 데이터버퍼 캐시영역에 로더되어 있는지 확인해 봅니다. 이때, 읽혀진 데이터를 데이터버퍼 캐시영역에 저장해야 하는데 데이터버퍼 캐시영역은 수많은 블록들로 구성되어 있기 때문에 매번 이 영역에서 빈 블록을 찾아 읽혀진 테이블 데이터를 저장하는 일은 너무 많은 시간이 필요하게 될 것이고 결국 성능을 저하시키게 될 것입니다.
예를 들어, 도서관의 선반에는 수많은 책들이 비치되어 있을 것입니다. 새로운 도서가 반입되어 책을 비치하려고 하는데 도서관 사서는 어떤 선반이 비어있는지를 책이 반입될 때마다 확인한 후 비치한다면 매번 반입작업을 처리하는데 많은 시간이 소요되어 일의 능률이 오르지 않을 것입니다. 이러한 문제를 극복하기 위해서 선반관리 리스트를 작성하며 책의 이동, 배치현황, 선반관리 등 정보를 미리 만들어 놓고 반입이 될 때마다 이 리스트를 통해 비어있는 선반을 쉽게 찾아낸다면 좋은 성능을 기대할 수 있을 것입니다.
데이터베이스에서도 마찬가지로 서버 프로세스가 매번 빈 블록을 데이터버퍼 캐시영역으로부터 직접 찾아낸다면 너무 많은 시간이 소요될 수 있기 때문에 미리 만들어져 있는 LRU-LIST를 통해 빈 블록을 쉽게 찾아냅니다.
이번에는 LRU-LIST를 통해 빈 블록을 찾아내는 방법입니다. 첫 번째는 [FREE BUFFER]이며 비어있는 버퍼공간으로 새로운 데이터를 저장할 수 있는 공간입니다. 최초 사용자에 의해 읽혀진 테이블 데이터가 저장될 수 있는 블록입니다.
두 번째로는 [PINED BUFFER]인데 [FREE BUFFER]이었다가 사용자에 의해 데이터가 저장된 후 트랜잭션이 진행 중인 데이터를 저장하고 있는 버퍼공간입니다.
마지막으로, [DIRTY-BUFFER]는 사용자에 의해 진행 중인 트랜잭션이 완료된 버퍼공간입니다. 또한, LRU-LIST의 가장 오른쪽을 [LRU-END]라고 하며 가장 왼쪽은 [MRU(MOST RECENTLY USED)-END]라고 합니다. [LRU-END] 부분에는 데이터버퍼 캐시영역의 블록들 중에 가장 오래 전에 사용한 블록 정보들이 배치되고 [MUR-END] 부분에는 가장 최근에 사용된 블록 정보들이 배치됩니다. 자~ 서버 프로세스에 의해 읽혀진 테이블 데이터를 데이터버퍼 캐시영역의 빈 블록에 저장하기 위해 서버 프로세스는 LRU-LIST의 LRU-END 부분 블록들 부터 MRU-END 부분으로 검색하면서 [FREE BUFFER] 블록을 찾습니다. 먼저, [D5] 블록을 읽었는데 이 블록은 [PINED BUFFER]이군요. 다른 사용자에 의해 사용되고 있는 버퍼공간이므로 이공간을 사용해서는 안될 것입니다.
다음은 [G9] 블록인데 [FREE-BUFFER] 블록이군요. 서버 프로세스는 데이터버퍼 캐시영역으로 가서 이 블록에 테이블 데이터를 저장하게 됩니다. 이제 [G9] 블록은 [FREE-BUFER]이었다가 [PINED-BUFFER]로 속성이 바뀌게 되었고 가장 최근에 사용한 블록이 되었기 때문에 MRU-END 부분으로 블록정보가 이동하게 됩니다. 즉, [A1] 블록정보 왼쪽에 [G9] 블록정보가 배치됩니다. 하나의 블록으로 읽혀진 데이터가 모두 저장되었다면 작업은 끝나게 될 것입니다. 만약, 하나의 블록으로 데이터를 모두 저장하지 못했다면 [FREE BUFFER]를 찾기 위한 노력은 계속 진행됩니다.
다음은 [S3] 블록인데 [PINED BUFFER]이므로 스킵, 다음은 [F2] 블록인데 [DIRTY BUFFER] 블록이군요. 이 블록은 다른 사용자에 의해 저장된 데이터가 COMMIT 또는 ROLLBACK 문장을 만나 트랜잭션이 완전히 끝난 블록이므로 빨리 테이블에 변경된 정보를 저장해야할 블록입니다. [FREE-BUFFER]를 찾기 위해 검색을 하다가 [DIRTY-BUFFER]를 만나게 되면 이 블록의 정보들은 DIRTY-LIST로 이동되어 별도로 관리됩니다. 그리고, 다시 다음 블록을 검색합니다.
이번에는 [K7] 블록, [FREE-BUFFER]이군요. 서버 프로세스는 읽혀진 데이터를 저장합니다. 이런 방법으로 계속해서 읽혀진 데이터를 저장하기 위해 [FREE-BUFFER]를 찾게되는데 너무 많은 사용자들이 이러한 작업을 하다보면 LRU-LSIT를 아무리 검색해도 [FREE-BUFFER]를 찾지 못하는 경우가 발생할 수도 있습니다. 이런 경우에는 DIRTY LIST에 저장된 블록 정보들을 DBWR 백그라운드 프로세스에 의해 테이블에 저장하고 그 블록들을 [FREE-BUFFER]로 만들어 새로운 데이터를 저장하게 됩니다.
서버 프로세스는 이러한 방법으로 데이터 파일로부터 읽은 데이터를 데이터버퍼 캐시영역에 저장하기 위해 [FREE-BUFFER]를 찾게되는데 이런 메커니즘을 LRU 알고리즘이라고 합니다. LRU 래치 "LRU 알고리즘"에서 사용자가 실행한 SQL문에 의해 테이블 데이터가 데이터버퍼 캐시 영역에 저장되기 위해서는 LRU LIST로부터 FREE BUFFER를 찾아야하는데, 만약 서버 프로세스가 하나의 FREE BUFFER를 찾았다면 이것을 "래치를 얻었다"라고 합니다. 하나의 서버 프로세스가 얻은 하나의 래치는 약 50개의 FREE BUFFER를 동시에 처리할 수 있습니다.
하나의 서버 프로세스는 지금 이 순간에도 하나의 래치를 얻기 위해 다른 서버 프로세스와 경합을 벌여 FREE BUFFER를 찾게 됩니다. 오라클 데이터베이스를 설치하면 LRU 래치의 기본 값은 1입니다. 사용자 수가 많은 데이터베이스 환경이라면 래치를 얻기 위한 경합(CONTENTION)으로 인해 성능이 저하될 수도 있습니다.
래치의 경합현상은 V$LATCH 자료사전을 통해 알 수 있는데 GETS 컬럼은 LATCH를 얻은 수이며 SLEEPS 컬럼은 LATCH를 얻지 못하고 대기(WAITING)했던 수를 의미합니다. DB_BLOCK_LRU_LATCHES = [n] 오라클 데이터베이스를 설치하면 LRU 래치의 기본 값은 1입니다. 이 값은 시스템의 CPU 수와 균형을 맞추어서 설정해야 하는데 최대 값은 (CPU 수 X 2 X 3 또는 데이터버퍼 수 / 50)계산에 의해 산출할 수 있으며 CPU수가 하나인 시스템 환경에서 래치수의 증가는 성능에 별로 도움이 안됩니다.
참 !!! 이 기능은 오라클 9i 버전에서 추가된 동적인 SGA 관리 기법을 사용할 때는 설정해 줄 필요가 없습니다. 래치 수를 오라클 서버가 자동으로 관리해 주기 때문입니다. 리두로그 버퍼 래치 오라클 데이터베이스 구조에서 발생하는 두 번째 래치는 리두로그 버퍼영역에서 발생합니다. 서버 프로세스가 변경 데이터를 저장하기 위해 먼저 리두로그 버퍼의 공간을 확보하게 되는데 이것을 리두할당 래치(Redo Allocation Latch)라고 합니다. 리두할당 래치를 입수한 서버 프로세스는 변경 데이터를 리두로그 버퍼에 저장해야 하는데 이것을 리두카피 래치(Redo Copy Latch)라고 합니다. 래치의 유형 오라클 데이터베이스에서 제공하는 래치는 다음과 같이 크게 2가지 유형이 있습니다. WILLING TO WAIT 타입 이 타입은 서버 프로세스가 래치를 이용할 수 없을 때 잠시 기다렸다가 다시 래치를 요청하고 또 이용할 수 없으면 기다렸다가 다시 래치를 요청하게 됩니다. 일정한 회수를 반복적으로 요청하다 계속 래치를 얻지 못하면 수면상태(SLEEP)에 빠졌다가 일정시간이 지나면 다시 래치를 요청하는 방법으로 운영됩니다. 리두할당 래치가 대표적인 WILLING-TO-WAIT 타입입니다. SQL> SELECT b.name, a.misses / a.gets "MISSES/GETS" FROM V$LATCH A, V$LATCHNAME B WHERE b.name = ('redo allocation') And b.latch# = a.latch#; NAME MISSES/GETS redo allocation .000023226 redo copy 0 <- WILLING-TO-WAIT 타입의 래치 경합이 발생하면 MISSES/GETS의 결과 값이 1% 이상의 값을 보이게 됩니다. MISSES의 경우는 래치를 얻지 못한 경우이며, GETS는 래치를 얻은 경우를 나타냅니다. 이런 경우에는 리두로그 버퍼가 너무 작아 경합이 발생하는 경우이므로 리두로그 버퍼의 크기를 보다 크게 늘려줘야 합니다. IMMEDIATE 타입 서버 프로세스가 WILLING-TO-WAIT 래치와 같이 요청된 래치를 이용할 수 없을 경우 기다리지 않고 바로 래치를 얻는 타입입니다. 리두카피 래치가 대표적인 IMMEDIATE 타입입니다. SQL> SELECT b.name, a.immediate_misses / decode((a.immediate_gets + immediate_misses), 0, 1, (a.immediate_gets + a.immediate_misses)) "MISSES/GETS" FROM V$LATCH A, V$LATCHNAME B WHERE b.name = ('redo copy') And b.latch# = a.latch#; NAME MISSES/GETS ------------------------------------------- --------------- redo allocation 0 redo copy .000118391 <- IMMEDIATE 타입의 래치 경합이 발생하면 MISSES/GETS의 결과 값이 1% 이상의 값을 보이게 됩니다. MISSES의 경우는 래치를 얻지 못한 경우이며, GETS는 래치를 얻은 경우를 나타냅니다. 이런 경우에는 리두로그 버퍼가 너무 작아 경합이 발생하는 경우이므로 리두로그 버퍼의 크기를 보다 크게 늘려줘야 합니다. 리두로그 래치의 튜닝 리두할당 래치에서 MISSES/GET의 비율이 1% 이상의 경합이 발생한다면 LOG_SMALL_ENTRY_MAX_SIZE 파라메터의 값을 감소시켜야 합니다. 만약, 변경 데이터의 양이 이 파라메터의 값보다 작으면 리두할당 래치를 얻은 상태에서 변경 데이터를 복사하는 작업까지 완료할 수 있고, 만약, 크다면 리두할당 래치를 할당 받은 후 래치를 해제하게 됩니다. 리두카피 래치에서 MISSES/GET의 비율이 1% 이상의 경합이 발생한다면 LOG_SMALL_ENTRY_MAX_SIZE 파라메터의 값이 작아서 리두할당 래치가 너무 빨리 해제되어 리두카피 래치가 시작되는 문제 때문에 발생한 것입니다. 리두카피 래치의 기본 수는 해당 시스템의 CPU 수이며 최대 CPU수의 2배까지 정의할 수 있습니다. LOG_SIMULTANEOUS_COPIES 파라메터에 의해 리두카피 래치수가 결정됩니다.
읽혀진 테이블 데이터가 없다면 데이터 파일로부터 테이블을 읽어서 데이터버퍼 캐시영역에 로더하게 될 것입니다
먼저, 데이터버퍼 캐시영역에는 3가지 종류의 버퍼타입이 있습니다
GETS 컬럼에 대해 SLEEPS 컬럼이 99% 이상의 백분율을 보일 때 경합이 발생하지 않기 때문에 좋은 성능을 기대할 수 있습니다. 만약, 백분율이 좋지 못하다면 다음 파라메터를 통해 래치 수를 더 높게 설정해 주어야 합니다.
많은 사용자들이 동시에 UPDATE, INSERT, DELETE문을 실행하면 변경 행의 이전 데이터와 이후 데이터가 모두 리두로그 버퍼영역에 저장되어야 합니다. 하지만 하나의 구조로 활성화되어 있는 메모리 공간에 많은 사용자들의 변경 데이터가 저장되려면 서로 리두로그 버퍼 영역을 사용하기 위해 경합을 벌여야 합니다. 결국 경합현상으로 인해 대기상태가 발생하게 되고 성능이 저하되게 됩니다.
이런 경우에는 리두카피 래치 수를 증가시켜 경합이 발생하지 않도록 해야 합니다.
[오라클]2-3단계 아카이브 파일 (0) | 2012.12.19 |
---|---|
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
[오라클]1-4단계 자바풀 영역 (0) | 2012.12.19 |
[오라클]1-3단계 로그버퍼 영역 (0) | 2012.12.19 |
[오라클]1-2단계 버퍼캐쉬 영역 (0) | 2012.12.19 |
|
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
---|---|
[오라클]1-5단계 래치와 경합 (0) | 2012.12.19 |
[오라클]1-3단계 로그버퍼 영역 (0) | 2012.12.19 |
[오라클]1-2단계 버퍼캐쉬 영역 (0) | 2012.12.19 |
[오라클]1-1단계 공유풀 영역 (0) | 2012.12.19 |
1-3 단계 : 로그버퍼영역
로그 버퍼 영역의 튜닝 분석 사용자들이 데이터베이스에 접속 한 후 INSERT, UPDATE, DELETE 작업을 실행하면 트랜잭션에 의해 만들어진 모든 변경정보(UPDATE문을 실행했다면 변경 전 데이터와 변경 후 데이터)가 로그버퍼 영역에 저장됩니다. 그러나, 로그버퍼 영역에는 사용자의 모든 변경된 데이터를 저장해 둘 수 없기 때문에 이 데이터들을 영구히 저장하기 위해 로그기록기(LGWR)에 의해 로그파일에 기록하게 됩니다.
리두로그 버퍼영역은 여려 명의 사용자가 같이 사용하는 공간이기 때문에 너무 많은 서버 프로세스가 동시에 많은 변경된 데이터를 저장하려고 한다면 서버 프로세스간에 경합(CONTENTION)이 발생할 것입니다. 또한, 사용자의 변경된 정보를 저장할 충분한 리두로그 버퍼공간이 없다면 미처 변경된 정보를 저장하지 못하고 대기(WAITING)해야 하는 경우도 발생할 것입니다.
이러한 문제가 발생하면 결국 UPDATE, INSERT, DELETE 시에 좋은 성능을 기대할 수 없습니다. 로그버퍼 영역의 크기는 INIT<DB명>.ORA 파일에 있는 LOG_BUFFER 파라메터에 의해 결정됩니다. 이 파라메터를 설정하지 않으면 오라클 서버는 블록크기(DB_BLOCK_SIZE 파라메터의 크기)의 4배 값을 기본 로그버퍼 영역의 크기로 할당합니다. 로그 버퍼 캐시 영역을 보다 크게 할당한다. 로그버퍼 영역에 대한 튜닝은 여러 사용자가 동시에 변경 작업을 했을 때 변경된 데이터를 저장할 만한 충분한 메모리 공간이 할당되어야 한다는 것입니다. 이 공간이 너무 작으면 서로 변경 데이터를 저장하기 위해 경합(CONTENTION)이 발생하고 결론적으로 어떤 서버 프로세스는 대기(WAITING) 상태가 발생할 것입니다.
다음은 자료사전을 통해 로그버퍼 영역을 분석하는 방법입니다. V$SESSION_WAIT 자료사전을 참조하면 이 영역에 대한 튜닝 여부를 확인할 수 있습니다
SECOND_IN_WAITS 컬럼의 값이 계속 증가되는 값을 나타내고 STATE 컬럼이 "WAITING"을 나타내면 로그버퍼 영역이 작아서 서로 프로세스간에 경합이 발생하고 있음을 의미합니다. SQL> SELECT sid, event, second_in_wait, state FROM v$session_wait WHERE event = 'log buffer space%'; SID EVENT SECOND_IN_WAIT STATE ----------------------------------------------------- 5 log buffer space 110 WAIT V$SYSSTAT 자료사전에서 서버 프로세스가 로그정보를 저장했던 로그버퍼의 블록 수(REDO ENTRIES)와 로그버퍼의 경합으로 인해 발생한 대기상태에서 공간이 생겨 다시 로그버퍼 공간을 할당 받았던 블록 수(REDO BUFFER ALLOCATION RETRIES)를 확인할 수 있습니다.
REDO BUFFER ALLOCATION RETRIES의 값은 0 이어야 하고 REDO ENTRIES 값의 1% 미만일 때 로그버퍼 영역에 대한 좋은 성능을 기대할 수 있습니다. SQL> SELECT name, value FROM v$sysstat WHERE name IN ('redo buffer allocation retries', 'redo entries'); NAME VALUE -------------------------------------------- redo entries 2015 redo buffer allocation retries 12 만약, 기준치에 적합하지 않은 결과가 나오면 리두로그 영역이 작아서 발생한 문제임으로 LOG_BUFFER 파라메터 값을 더 높게 설정해야 합니다. $ cd $HOME/dbs $ vi init<SID>.ora LOG_BUFFER = 8192 ß 이전 값 보다 더 크게 설정해야 합니다. :wq! 인덱스 생성시 NOLOGGING절을 적용한다. 사용자가 테이블을 생성하고 데이터를 입력, 수정, 삭제하면 트랜잭션에 의해 발생한 모든 변경 전, 변경 후 정보가 로그버퍼 영역에 저장되는데 이러한 방법을 로깅모드(LOGGING)라고 합니다. 테이블, 인덱스를 생성할 때 NOLOGGING 키워드를 사용하면 생성 후 발생하는 모든 트랜잭션의 로그정보가 로그버퍼 영역에 저장되지 않습니다. 만약, 해당 테이블의 데이터가 다른 시스템 또는 다른 데이터베이스로부터 이동된 테이블이거나 언제든지 복구가 가능한 테이블이라면 LOGGING 모드로 데이터베이스를 사용하는 것보다 NOLOIGGING 모드로 사용하는 것이 로그버퍼 영역을 적게 사용하기 때문에 로그버퍼 영역에 대한 경합 현상을 최소화시킬 수 있습니다. 인덱스는 테이블을 통해 언제든지 만들 수 있기 때문에 NOLOGGING모드로 만드는 것이 좋은 성능에 도움이 될 수 있습니다.
다음 예제를 따라 해 보세요. SQL> CONNECT scott/tiger SQL> CREATE TABLE emp10 (no NUMBER, name VARCAHR2(10)) NOLOGGING; SQL> ALTER TABLE emp10 LOGGING; SQL> CREATE INDEX I_emp10 ON emp10 NOLOGGING; 앞에서도 언급되었듯이 테이블을 NOLOGGING 모드로 설정할 때는 데이터의 유형과 복구 전략에 대한 충분한 고려를 한 후 결정해야 하며, 인덱스에 대해선 자주 변경이 발생하는 테이블에 대해 적용한다면 INSERT, UPDATE, DELETE 작업 시 보다 빠르게 변경작업을 수행할 수 있을 것 입니다. 만약, 데이터베이스에 문제가 발생하여 복구작업을 수행해야 한다면 인덱스의 경우에는 재 생성하는 것이 복구이기 때문에 반드시 LOGGING 모드일 필요가 없습니다.
EMP10 테이블을 NOLOGGING 키워드로 생성하고 다시 LOGGING 모드로 바꿔보십시오. 그리고, I_EMP10 인덱스를 NOLOGGING 모드로도 생성해 보십시오.
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
---|---|
[오라클]1-5단계 래치와 경합 (0) | 2012.12.19 |
[오라클]1-4단계 자바풀 영역 (0) | 2012.12.19 |
[오라클]1-2단계 버퍼캐쉬 영역 (0) | 2012.12.19 |
[오라클]1-1단계 공유풀 영역 (0) | 2012.12.19 |
1-2 단계 : 버퍼캐쉬 영역
데이터 버퍼 캐시 영역의 튜닝 분석 "SQL문의 처리과정"을 통해 알아보았듯이 데이터 파일로부터 읽혀진 데이터가 저장되는 메모리 영역을 데이터버퍼 캐시영역이라고 하며 이 영역의 크기는 INIT<DB명>.ORA 파일에 정의되는 DB_CACHE_SIZE 파라메터에 의해 결정됩니다. 예를 들어, 윈도우 시스템에서 어떤 텍스트 파일의 내용을 편집하기 위해 더블-클릭을 하면 잠시 후 편집기 프로그램이 실행되고 파일의 내용이 화면에 출력됩니다.
이와 같이 실행되는 과정을 살펴보면 선택된 파일은 디스크로부터 읽혀지고 시스템의 메모리 버퍼영역에 로더된 다음 편집기를 통해 사용자의 화면에 출력되는 것 입니다. 만약, DB_CACHE_SIZE 파라메터의 값이 10MB일 때 읽혀지는 테이블의 크기는 20MB이라면 어떻게 될까요 ? 읽혀지는 테이블이 메모리 크기보다 크기 때문에 한번에 테이블 데이터 모두를 메모리에 저장하지 못하고 2번에 나누어서 저장해야 할 것입니다.
그렇다면, DB_CACHE_SZIE가 20MB이라면 어떻게 될까요 ? 당연히 읽혀진 테이블 데이터 20MB를 한번에 데이터버터 캐시영역에 저장하게 될 것입니다. 2번 이상, 여러 번 나누어서 데이터를 처리하는 것보다는 한번에 데이터를 처리하는 것이 좋은 성능을 기대할 수 있는 방법이 될 것입니다. 결론적으로, 데이터버퍼 캐시영역의 크기는 처리하려는 테이블 데이터를 충분히 로더할 수 있을 만큼 설정되어 있는 경우와 그렇지 못한 경우에 의해 성능차이가 발생할 수 있다는 것입니다. 데이터 버퍼 캐시 영역의 튜닝 방법 데이터 버퍼 캐시 영역을 보다 크게 할당한다. 그럼, 데이터버퍼 캐시영역에 대한 성능을 향상시킬 수 있는 첫 번째 방법을 알아 보겠습니다. 사용자가 질의한 데이터를 데이터버퍼 캐시영역에 로더하려면 충분한 메모리 공간이 필요합니다. 공간이 부족하면 한번에 데이터를 로더하지 못하고 여러 번 나누어서 로더해야 하기 때문에 성능이 저하될 수 있습니다.
다음은 자료사전을 통해 데이터 버퍼 캐시영역의 튜닝 상태를 분석하는 방법입니다. $ sqlplus scott/tiger
SQL> select * from big_dept;
SQL> select * from big_emp;
SQL> connect system/manager
SQL> select 1 - ((phy.value)/(cur.value + con.value)) "CACHE HIT RATIO"
from v$sysstat cur, v$sysstat con, v$sysstat phy
where cur.name = 'db block gets'
and con.name = 'consistent gets'
and phy.name = 'physical reads';
CACHE HIT RATIO
-----------------
.973257182 "PHYSICAL READS"는 사용자가 SQL문을 실행했을 때 데이터 파일로부터 테이블을 읽은 블록 수를 의미하며 "DB BLOCK GETS"는 DML문의 처리과정에서 처럼 데이터버퍼 캐시영역에 있는 변경 후 데이터를 참조할 때 읽은 블록 수를 의미합니다. "CONSISTENT GETS"은 변경작업 후 ROLLBACK문을 실행했을 때 변경 전 데이터로 복구하기 위해 이전 데이터를 저장해 두는 메모리 영역으로부터 읽은 블록 수입니다.
즉, "PHYSICAL READS"는 물리적 구조에서 읽은 블록 수이며 "DB BLOCK GETS"와 "CONSISTE NT GETS"는 논리적 구조(메모리 영역)에서 읽은 블록 수를 의미합니다. 되도록, 하나의 테이블을 질의할 때 물리적 구조로부터 데이터를 읽는 것보다는 논리적 구조로부터 읽은 블록 수가 더 많아야 성능에 도움이 될 것입니다. 만약, 충분한 데이터 버퍼 공간이 확보되었다면 "DB BLOCK GETS"와 "CONSISTENT GETS"가 더 높은 값이 출력될 것입니다.
그리고, 다음과 같은 공식에 의해 캐시 히트율을 계산할 수 있는데 이것은 사용자가 실행한 SQL문의 테이블이 이미 다른 사용자에 의해 읽혀져서 데이터버퍼 영역에서 발견되었던 블록 히트율 = 1 - (PHYSICAL READS / (DB BLOCK GETS + CONSISTENT GETS)) 캐시 히트율이 90% 이상일 때 충분한 데이터버퍼 캐시영역이 설정되어 있고 좋은 성능을 기대할 수 있습니다. 만약, 캐시 히트율이 좋지 못하다면 다음 파라메터를 통해 데이터버퍼 캐시영역의 크기를 크게 설정해 주어야 합니다. $ cd $HOME/dbs
$ vi init.ora
………………………
DB_CACHE_SIZE = [크기]
:wq! <잠깐> 오라클 9i 이전 버전에서는 DB_CACHE_SIZE 파라메터가 DB_BLOCK_SIZE와 DB_BLOCK_BUFFERS 파라메터로 나누어져 사용되었습니다. 2개 파라메터 값을 곱한 결과가 DB_CACHE_SIZE의 값과 같습니다. 멀티 버퍼 캐시영역을 할당한다. 일반적으로 오라클 데이터베이스의 SGA 영역에는 데이터 버퍼 캐시영역이 하나의 구조로 생성되는데 이 영역을 데이터의 성격과 크기에 따라 여러 개의 영역으로 나누어 생성할 수 있는 기법을 멀티 버퍼캐시 영역이라고 합니다.
위 그림에서 보시는 것처럼 데이터버퍼 캐시영역을 3가지 영역으로 나누어 생성할 수 있습니다. 첫 번째 영역은 KEEP 데이터버퍼 캐시 영역입니다. 이 영역은 운영되는 데이터베이스 환경에서 빈번하게 사용되는 테이블 데이터를 계속 데이터버퍼 캐시영역에 상주시키기 위한 공간입니다. 이 공간에 저장될 수 있는 테이블은 그 크기가 너무 크면 안되고 사용자에 의해 빈번하게 사용되는 테이블이어야 합니다.
예를 들어, 부서 테이블, 사원 테이블, 코드 테이블 등은 모든 애플리케이션 프로그램에서 항상 참조되며 또한 테이블의 크기가 크지 않기 때문에 가장 적합한 테이블입니다.
두 번째 영역은 RECYCLE 데이터 버퍼 캐시영역입니다, 이 영역에는 자주 사용되지 않고 가끔 사용되는 테이블이면서 테이블의 크기가 아주 큰 테이블을 검색할 때 사용됩니다. 사용자에 의해 검색된 테이블은 이 영역에 데이터를 로더한 후 작업이 완료되면 모두 클리어(CLEAR) 됩니다. DB_CACHE_SIZE = [크기] DB_CACHE_SIZE 파라메터는 DEFAULT 데이터버퍼 캐시영역의 크기를 의미합니다. 다음은 다중 풀 영역에 로더될 테이블을 다음과 생성해야 합니다. < 문법 >
CREATE TABLE [테이블명]
([컬럼-1] [데이터 타입],
…………………………………….
[컬럼-N] [데이터 타입])
STORAGE ( BUFFER_POOL [KEEP | RECYCLE] );
ALTER TABLE [테이블명]
STORAGE ( BUFFER_POOL [KEEP | RECYCLE] ); KEEP 데이터버퍼 캐시영역 자~ 그렇다면 KEEP 데이터버퍼 캐시 영역를 설정하고 싶은데 그 크기는 얼마나 할당해야 할까요 ? 크기를 설정하는 방법은 다음과 같습니다. $ sqlplus scott/tiger SQL> analyze table big_emp compute statistics; SQL> analyze table big_dept compute statistics; SQL> select table_name, blocks from user_tables where table_name in ( 'BIG_EMP' , 'BIG_DEPT' ); TABLE_NAME BLOCK
----------------------------------------- BIG_DEPT 5 <- 14 행을 저장하고 있슴 BIG_EMP 370 <- 28955 행을 저장하고 있슴 <-sum(blocks + 1) 을 모두 포함할 만큼의 충분한 크기로 keep buffer pool을 설정해야 합니다. ANALYZE 명령어를 실행하면 분석결과가 DBA_TABLES, USER_TABLES 자료사전에 저장 됩니다. $ cd $ORACLE_HOME/dbs $ vi init<DB명>.ora DB_KEEP_CACHE_SIZE = 4M ß BIG_DEPT, BIG_EMP 가 상주될 메모리 공간 DB_RECYCLE_CACHE_SIZE=4M ß RECYCLE 영역 :wq! $ sqlplus "/as sysdba" SQL > startup force ß Shutdown 후 다시 Startup SQL > show parameter db_keep_cache_size NAME TYPE VALUE db_keep_cache_size big integer 8388608 RECYCLE 데이터버퍼 캐시영역 이번에는 RECYCLE 데이터버퍼 캐시 영역를 설정하고 싶은데 그 크기는 얼마나 할당해야 할까요 ? 크기를 설정하는 방법은 다음과 같습니다. SQL> CONNECT SYS/CHANGE_ON_INSTALL AS SYSDBA SQL> show parameter db_recycle_cache_size NAME TYPE VALUE ---------------------------------------------------------- db_recycle_cache_size big integer 8388608 SQL> START $HOME/rdbms/admin /catparr.sql SQL> SELECT owner#, name, count(*) blocks FROM v$cache WHERE name = 'EMP' GROUP BY owner#, name; OWNER NAME BLOCK 5 EMP 200 실행된 결과가 V$CACHE 자료사전에 저장됩니다. 이 결과에서 해당 테이블이 데이터버퍼 캐시영역에서 필요로 하는 블록 수가 어느 정도인지 알 수 있습니다. 이 블록 수의 1/4 값을 DB_RECYCLE_CACHE_SIZE 파라메터에 설정하십시오. RECYCLE 영역에는 가끔 질의되는 테이블 데이터가 저장될 메모리 공간이기 때문에 결과의 전체 블록 수를 설정할 필요가 없습니다. SQL > select name, buffers from v$buffer_pool; NAME BUFFERS -------------- ----------- KEEP 1934 <- KEEP 영역의 크기 RECYCLE 1934 <- RECYCLE 영역의 크기 DEFAULT 967 <- DEFAULT 영역 크기 다중 버퍼 캐시영역이 활성화 되었으면 개발자가 실행할 테이블 중에 KEEP 영역과 RECYCL $ sqlplus scott/tiger SQL> alter table big_emp storage ( buffer_pool keep); SQL> alter table big_dept storage ( buffer_pool keep); SQL> alter table account storage ( buffer_pool recycle); 각 테이블이 어떤 버퍼 캐시영역에 로더 되는지를 확인하는 방법입니다. SQL> select table_name, buffer_pool from user_tables where table_name in ( 'BIG_EMP' , 'BIG_DEPT' ); TABLE_NAME BUFFER_ ---------------- ------- BIG_EMP KEEP <-KEEP 될 테이블 정보를 의미합니다. SQL> SELECT * FROM big_dept; SQL> SELECT * FROM big_emp; SELECT * FROM account; 다음 문장은 다중 버퍼 캐시영역의 현재 튜닝상태를 제공해 줍니다, SQL> select name, 1-(physical_reads/(db_block_gets+consistent_gets)) "Multiple RATIO" from v$buffer_pool_statistics where db_block_gets + consistent_gets > 0 ; NAMA Multiple RATIO ----------- --------------- KEEP .839300938 <-100 %에 가까울수록 최적 RECYCLE .819349315 <-50 %가 최적 DEFAULT .752205989 <-90 % 이상이 가장 최적 KEEP 영역은 모든 테이블을 캐싱하기 위한 공간이므로 100% 히트율을 유지하는 것이 좋은 성능을 제공하고, RECYCLE 영역은 잠깐 사용되는 공간이므로 50% 히트율로도 충분하며, DEFAULT 영역은 일반적으로 사용되는 공간이므로 90% 히트율을 유지하는 것이 좋습니다. <잠깐>오라클 8i 버전에서 멀티 버퍼 캐시 영역의 활성화 방법 오라클 9i 이전 버전과 이후 버전에서 멀티 버퍼캐시 영역을 활성화하는 방법의 차이는 문법적인 측면입니다. 즉, 9i 버전에서는 SGA 영역을 동적으로 관리하는 기능이 추가되었기 때문에 이와 관련된 문법이 변경되었습니다 $ vi init<SID>.ora DB_BLOCK_BUFFERS = 3147 DB_BLOCK_LRU_LATCHES = 6 BUFFER_POOL_KEEP = (BUFFERS:1400, LRU_LATCHES:1) BUFFER_POOL_RECYCLE = (BUFFERS:200, LRU_LATCHES:3) <잠깐>오라클 8i 버전에서 멀티 버퍼 캐시 영역의 활성화 방법 ID NAME LO_SETID HI_SETID SET_COUNT BUFFERS LO_BNUM JI_BNUM
-------------------------------------------------------------------------------------
0 0 0 0 0 0 0
1 KEEP 3 3 1 1400 0 0
2 RECYCLE 4 6 3 200 0 0
3 DEFAULT 1 2 2 1547 1600 0 DB_BLOCK_BUFFERS와 DB_BLOCK_SIZE 파라메터가 오라클 9i에서 DB_CACHE_SIZE 파라메터로 바뀌었고, DB_BLOCK_LRU_LATCHES와 같은 래치 파라메터는 오라클 서버가 자동 관리해 주는 방법으로 변경되어 9i에서는 정의하지 않습니다. 자주 사용되는 테이블을 캐싱한다. 다중 멀티 풀 영역을 이용한 성능향상 기법이 오라클 8 버전부터 추가된 기능이라면 캐싱 테이블 기법은 오라클 이전 버전부터 사용되던 기법입니다. 사용자가 실행한 SQL문에 의해 테이블 전체 스캔 방법으로 테이블이 검색된 후 계속해서 데이터 버퍼 캐시영역에 상주하게 됩니다.
정상적인 데이터버퍼 캐시 메커니즘이라면 다른 서버 프로세스에 의해 데이터버퍼 캐시영역은 재 사용되겠지만 캐싱 테이블로 만들어진 블록들은 다른 서버 프로세스에 의해 재 사용되지 않고 계속해서 상주할 수 있게 되는 기능입니다. 다중 멀티 풀 영역에서 KEEP 데이터버퍼 캐시영역과 유사한 기능을 가지고 있습니다. 이 기법을 통해 빈번하게 사용되는 테이블을 데이터버퍼 캐시영역에 상주시키면 검색 시 성능을 향상시킬 수 있습니다.
다음 문법은 캐시 테이블을 생성하는 방법입니다. 문법 CREATE TABLE [테이블명] ([컬럼] [데이터타입]) [CACHE / NOCACHE]; ALTER TABLE [테이블명] [CACHE] /NOCACHE]; 테이블을 생성할 때 [CACHE] 키워드를 사용하십시오. 또는, 이미 생성되어 있는 테이블을 [CACHE] 키워드로 변경할 수도 있습니다. 또한, [CACHE]된 테이블을 [NOCACHE]로 변경할 수도 있습니다. 만약, CACHE된 테이블 데이터가 [NOCACHE]로 바뀌면 데이터베이스가 종료되고 다시 시작될 때 적용됩니다.
다음 예제를 따라 해 보세요. DBA_TABLES, USER_TABLES 자료사전을 검색해 보면 어떤 테이블이 캐시 테이블로 생성되어 있는지를 알 수 있습니다. SQL> alter table big_dept cache; SQL> select table_name, cache from user_tables where table_name in ('BIG_EMP' , 'BIG_DEPT'); TABLE_NAME CACHE BIG_DEPT Y BIG_EMP Y <-데이터 버퍼캐시 영역에 상주되는 테이블을 SQL> SELECT * FROM big_dept; SQL> SELECT * FROM big_emp; 다음은 캐시 테이블로 생성하지는 않았지만 힌트절을 통해 테이블을 캐싱하는 방법입니다. SQL> SELECT /*+CACHE*/ Multiple Block 구조 오라클 데이터베이스에서 테이블에 대해 읽기/쓰기 작업을 수행할 때 한번에 읽고 쓸 수 있는 데이터의 크기를 블록(Block)이라고 합니다.
하나의 블록크기는 오라클 데이터베이스가 설치될 때 init<SID>.ora 파일에 정의되는 DB_ BLOCK_SIZE 파라메터에 의해 결정됩니다. 그리고, 이 값은 더 이상 변경할 수 없습니다.
만약, 대용량의 데이터를 저장하고 있는 테이블에 대해 읽기작업을 실행했을 때 DB_BLOCK_SIZE가 4K(4096 Byte)인 경우보다 8K(8192 Byte)인 경우가 한번에 읽을 수 있는 데이터가 크기 때문에 약 2배 이상 빠르게 검색할 수 있을 것 입니다.
오라클 8i 버전까지는 설치할 때 결정된 한 개 블록의 크기를 더 이상 변경하지 못하여 대용량 데이터를 처리해야 하는 경우 근본적인 구조변경을 하지 못하였습니다. 다음 내용은 블록의 크기가 작은 경우와 큰 경우에 대한 비교 분석된 내용입니다. 먼저, 다중 블록크기를 설정하기 위해서는 데이터 버퍼 캐시영역에 각 블록크기에 대한 전용 데이터 버퍼 캐시영역을 활성화해야 하고 테이블스페이스 생성시 적절한 블록크기를 정의하게 되면 사용가능 합니다. init<SID>.ora 파일에 관련 파라메터 들을 설정하십시오. $ vi init<SID>.ora DB_BLOCK_SIZE = 2048 기본 블록크기 DB_4K_CACHE-SIZE = 8M 4K 블록크기를 설정한 테이블스페이스를 위한 메모리 공간 DB_8K_CACHE-SIZE = 16M 8K 블록크기를 설정한 테이블스페이스를 위한 메모리 공간 DB_16K_CACHE-SIZE = 32M 16K 블록크기를 설정한 테이블스페이스를 위한 메모리 공간 DB_32K_CACHE-SIZE = 64M 32K 블록크기를 설정한 테이블스페이스를 위한 메모리 공간 <- 이 파라메터들에 의해 SGA 영역에는 2K, 4K, 8K, 16K, 32K 블록크기를 가진 데이터가 읽혀질 때 저장될 전용 메모리 공간이 각각 활성화됩니다. 대용량 데이터를 저장해야 할 데이터가 저장될 테이블스페이스를 생성하십시오. SQL> CREATE TABLESPACE INSA DATAFILE '$HOME/dbs/insa01.dbf' size 10m blocksize 4k; SQL> create table emp_test (A number) SQL> select * from user_tables where table_name = 'EMP_TEXT'; DB 캐시 영역의 시뮬레이션 이 기능은 오라클 데이터베이스의 SGA 영역에 활성화 되어 있는 데이터 버퍼 캐시영역에 대한 시물레이션 기능에 대해서 소개하고자 합니다.
오라클 9i 버전에서는 DB_CACHE_SIZE 파라메터에 의해 데이터 버퍼캐시 영역의 크기가 결정되는데 이 공간의 크기가 너무 작게 설정되어 있으면 데이터를 검색할 때 성능이 저하되고 또한 너무 크게 설정되어 있으면 메모리의 낭비가 초래될 수 있는 단점을 가지고 있습니다. DB_CACHE_ADVICE 파라메터를 ON으로 활성화하게 되면 현재 데이터 버퍼 캐시영역의 각 블록구조의 활용상태를 시뮬레이션 할 수 있습니다.
[OFF]로 설정되면 데이터 버퍼 캐시영역에 대한 시뮬레이션을 하지 않습니다. 위 그림에서 V$DB_CACHE_ADVICE 자료사전을 분석하여 데이터 버퍼 캐시영역을 분석하고 있습니다. SIZE_FOR_ESTIMATE 컬럼은 데이터 버퍼캐시 영역을 3M 단위로 시뮬레이션하는 것을 나타내는 것이며 BUFFERS_FOR_ESTIMATE 컬럼은 3M 단위의 버퍼크기에 대한 블록 수를 나타내며 ESTD_PHYSICAL_READ_FACTOR와 ESTD_PHYSICAL_READS 컬럼은 각 버퍼크기에 대한 사용된 회수를 보여주고 있습니다.
만약, 특정 메모리 영역에서 주로 작업이 발생하고 어떤 메모리 영역에서는 작업이 거의 일어나지 않는다면 불필요한 메모리 공간이 낭비되고 있음을 의미하는 것이며, 만약, 모든 메모리 영역에서 빈번한 읽기 작업이 발생한다면 오히려 데이터 버퍼 캐시영역의 크기가 너무 작아 성능저하가 발생하고 있음을 나타냅니다 <잠깐>
다음은 오라클 이전 버전까지 제공되던 데이터 버퍼 캐시 영역의 이 기능을 사용하기 위해서는 DB_BLOCK_LRU_EXTENDED_STATISTICS 파라메터를 설정해야 합니다. 위 그림에서 데이터 버퍼캐시 영역의 블록 개수를 200개로 설정했을 때 각 블록구조의 사용된 회수를 V$CURRENT_BUCKET 자료사전을 통해 분석할 수 있습니다. 이 결과를 통해 현재 데이터 버퍼 캐시영역의 크기가 적절한지를 알 수 있습니다. DB 캐시 영역의 시뮬레이션 사용자가 실행하는 SQL문에 의해 테이블이 디스크로부터 읽혀져서 메모리에 로더된 다음 서버 프로세스에 의해 다시 읽혀져 사용자에게 리턴되는 과정에서 데이터 버퍼 캐시영역의 히트율이 얼마나 되는지를 분석해 봅시다.
사용자의 요청에 의해 읽혀지는 테이블들이 디스크보다는 메모리로부터 읽혀진다면 히트율은 보다 높아질 것이며, 그렇지 않다면 히트율은 낮아질 것 입니다. 결론적으로 히트율이 높아진다면 보다 성능은 향상될 수 있을 것 입니다. SQL> SELECT 1 - (phy.value - lob.value - dir.value) / ses.value "Hit Ratio" FROM v$sysstat ses, v$sysstat lob, v$sysstat dir, v$sysstat phy WHERE ses.name = 'session logical reads' AND dir.name = 'physical reads direct' AND lob.name = 'physical reads direct (lob)' AND phy.name = 'physical reads'; Hit Ratio --------- .849176501 <- 히트율이 90% 이상일 때 좋은 성능이 기대될 수 있습니다. [physical reads]는 디스크로부터 읽은 블록 수이며
[physical reads direct]는 메모리로부터 읽은 블록 수이고,
[physical reads direct (lob)]는 Large Object Binary를 읽은 블록 수이고,
[session logical reads]는 해당 세션에서 논리적으로 읽은 블록 수입니다.
V$SYSSTAT 자료사전을 참조하면 이 영역에 대한 튜닝 여부를 확인할 수 있습니다.
수를 백분율로 계산한 것입니다.
마지막으로, DEFAULT 데이터 버퍼 캐시영역은 하나의 데이터버퍼 캐시영역을 가진 환경에서 사용되던 구조와 동일한 의미를 가집니다. 즉 여러 사용자에 의해 공용으로 사용되는 메모리 공간입니다. 다음은 다중 풀 영역을 설정하는 파라메트들 입니다.
DB_KEEP_CACHE_SIZE = [크기]
DB_KEEP_RECYCLE_SIZE = [크기]
DB_KEEP_CACHE_SIZE 파라메터는 KEEP 데이터버퍼 캐시영역의 크기를 의미합니다.
DB_KEEP_RECYCLE_SIZE 파라메터는 RECYCLE 데이터버퍼 캐시영역의 크기를 의미합니다.
먼저, ANALYZE 명령어를 실행하여 캐싱하려는 테이블이 몇 개의 블록으로 구성되어 있는지를 분석해야 합니다. 테이블의 모든 데이터를 KEEP 데이터버퍼 영역에 저장하기 위해서 테이블의 실제 블록 수를 분석하는 것입니다.
만약, KEEP 데이터버퍼 캐시영역에 5개의 테이블을 저장하고 싶다면, 이러한 방법으로 각 테이블의 블록 수를 분석한 다음 전체 블록 수를 집계하여 그 값을 DB_KEEP_CACHE_SIZE 파라메터에 할당해 주면 됩니다.
먼저, V$CACHE 자료사전을 참조하기 위해서 $HOME/rdbms/admin 경로에 있는 CATPARR.SQL 스크립트를 실행하십시오.
현재 데이터베이스에 설정된 다중 풀 영역에 대한 정보를 참조할 때는 V$BUFFER_POOL_STA TISTICS와 V$BUFFER_POOL 자료사전을 참조하십시오.
영역에 로더될 테이블을 결정합니다.
deptno, dname, loc
FROM big_dept;
SQL> EXIT
오라클 9i 버전에서는 이러한 문제점을 해결하여 테이블스페이스를 생성할 때 특별한 블록크기를 지정하지 않으면 설치할 때 정의된 DB_BLOCK_SIZE 파라메터 값으로 결정하고, 대용량의 데이터를 저장하고 검색하는 테이블이 존재하는 테이블스페이스를 생성할 때는 별도로 블록크기를 보다 크게 설정할 수 있습니다. 이러한 기능을 다중 블록(Multiple Block)구조라고 합니다.
그렇다면 모든 사용자가 실행하는 SQL문을 보다 빠르게 처리할 수 있을 만큼 적절한 메모리 공간이 확보되어 있는지를 확인할 수 있어야 할 것 입니다.
[READY]는 향후 시뮬레이션을 위한 통계정보 만 수집하고 실제적인 시뮬레이션은 하지 않습니다. 이 값에 의해 수집된 통계정보는 공유 풀 영역에 약 700 바이트 만큼의 공간을 사용합니다.
[ON]은 지금 즉시 통계정보 수집 후 데이터 버퍼 캐시영역에 대한 시뮬레이션을 시작합니다.
시뮬레이션 방법입니다.
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
---|---|
[오라클]1-5단계 래치와 경합 (0) | 2012.12.19 |
[오라클]1-4단계 자바풀 영역 (0) | 2012.12.19 |
[오라클]1-3단계 로그버퍼 영역 (0) | 2012.12.19 |
[오라클]1-1단계 공유풀 영역 (0) | 2012.12.19 |
1-1 단계 : 공유풀 영역
공유 풀 영역을 보다 크게 할당한다 공유 풀 영역을 보다 크게 할당한다. INIT<SID>.ORA 파일의 SHARED_POOL_SIZE 파라메터에 의해 공유 풀 영역의 크기는 결정됩니다. 하지만 너무 많은 사용자들이 너무 많은 SQL문을 실행하면 구문 분석된 정보가 모두 라이브러리 캐시영역에 저장됩니다. 새로운 사용자가 데이터베이스에 접속하고 새로운 SQL문을 실행했다면 그 문장은 서버 프로세스에 의해 구문 분석되어 라이브러리 캐시영역에 저장될 것입니다.
그런데, 불행하게도 라이브러리 캐시영역은 이미 빈 공간이 모두 사용되어 풀(FULL)된 상태입니다. 이런 경우가 발생하면 오라클 서버 프로세스는 로더를 하지 않고 잠시 대기(WAITING)한 후 로더되어 있는 SQL문 중에 가장 오래된 SQL문을 찾아내어 그 정보를 라이브러리 캐시영역으로부터 제거하게 됩니다. 이런 과정을 통해 확보된 빈 공간에 사용자의 새로운 SQL문 정보를 저장하게 됩니다. 이러한 방법을 AGING 메커니즘이라고 합니다.
하지만, 이러한 공간관리로 인해 생기는 문제점은 라이브러리 캐시영역에서 빈 공간을 확보하기 위해 가장 오래된 SQL문을 제거한 후 동일한 문장이 다른 사용자에 의해 재 실행될 때 구문분석을 다시 한다는 점입니다. 즉, 다시 재 실행될 SQL문의 구문분석 정보가 불필요하게 메모리로부터 제거되기 때문에 재 파싱이 발생하여 SQL문의 성능저하 현상이 초래될 수 있다는 점입니다. 이러한 문제점은 결국 라이브러리 캐시영역의 크기가 너무 작아서 발생한 문제이므로 공유 풀 영역의 크기를 더 크게 할당해 주어야 만 성능을 향상시킬 수 있습니다. 라이브러리 캐시영역의 튜닝분석
지금까지, 라이브러리 캐시영역에 대한 튜닝개념에 대해서 알아보았습니다. 그렇다면, 데이터베이스의 라이브러리 캐시 영역의 크기가 너무 작아 성능이 저하되고 있는지 또는 너무 크게 설정되어 있어 메모리가 낭비되고 있는지를 데이터베이스 관리자가 분석할 수 있어야 만 튜닝 계획을 수립할 수 있을 것입니다. 다음은 자료사전을 통해 라이브러리 캐시영역을 분석하는 방법입니다. 먼저, V$LIBRARYCACHE 자료사전을 통해 히트율(GETHITRATIO)을 분석할 수 있습니다. 히트율이란 V$LIBRARYCACHE 테이블의 GET 컬럼과 GETHITS 컬럼을 백분율로 계산한 값으로 GET은 사용자가 실행한 SQL문이 구문 분석되어 라이브러리 캐시영역에 로더되려고 했던 수이며 GETHITS는 그 중에 로더 되었던 수를 의미합니다. 즉, 라이브러리 캐시영역이 충분한 공간을 할당하고 있어서 사용자의 모든 구문분석 정보를 로더하기에 충분한가를 백분율로 계산해 본 것입니다. 히트율이 90% 이상일 때 좋은 성능을 기대할 수 있습니다.
다음은 히트율을 확인하는 방법입니다. SQL> SELECT namespace, gets, gethits, gethitratio FROM v$libraycache WHERE namespace = 'SQL AREA'; NAMESPACE GETS GETHITS GETHITRATIO SQL AREA 8950 8411 .936779536 GETHITRATIO 컬럼의 값이 90% 이상이면 라이브러리 캐시영역이 개발자들의 SQL 파싱정보를 저장하기에 충분한 메모리 공간을 확보하고 있음을 의미하며, 만약 90% 이하라면 성능이 저하될 수 도 있다는 것을 의미합니다. 물론, 90% 이하라도 사용자들이 성능에 만족한다면 튜닝대상이 안될 수도 있으며 반드시 튜닝을 해야 할 필요가 없다는 것 입니다. <잠깐> 이러한 히트율의 분석은 기업에서 가장 바쁘게 일을 진행하고 있는 시간대에 분석결과를 기준으로 설명되는 것입니다. 아무도 일을 하고 있지 않는 야간에 결과를 분석한다면 아무런 의미가 없겠죠 ?? 조치사항 히트율이 90% 이하이면 다음과 같이 SHARED_POOL_SIZE 파라메터의 값을 높게 설정해야 합니다. $ cd $HOME/dbs 두 번째로는, V$LIBRARY 자료사전을 통해 RELOAD 비율을 분석할 수 있습니다. RELOADS 비율이란 PINS 컬럼에 대한 RLOADS 컬럼의 백분율을 RELOADS 비율이라고 합니다. 이것은 라이브러리 캐시영역의 크기가 너무 작을 때 사용자의 SQL 구문분석 정보가 로더되지 못하고 가장 오래된 SQL문 정보를 라이브러리 캐시영역에서 삭제한 후 그 문장이 다시 실행될 때 RELOADS 컬럼 값이 증가하게 됩니다. 또는 구문 분석된 SQL문에서 사용된 객체가 다른 사용자에 의해 삭제된 상태에서 다시 SQL문이 재실행되면 발생합니다. PINS는 구문 분석되어 라이브러리 캐시영역에 저장될 수 있었던 SQL 정보를 의미합니다. 다음은 PINS에 대한 RELOADS의 비율을 확인하는 방법입니다. SQL> SELECT sum(pins), sum(reloads), sum(reloads) / sum(pins) FROM v$libraycache WHERE namespace = 'SQL AREA'; SUM(PINS) SUM(RELOADS) SUM(RELOADS)/SUM(PINS) 36299 45 0.001239704 PINS에 대한 RELOADS의 비율이 1% 미만일 때 라이브러리 캐시영역의 크기가 SQL 파싱 정보를 저장하기에 충분하다는 것을 의미합니다. 1% 이상이라면 성능이 저하될 수 도 있다는 것을 의미합니다. 마지막으로, V$LIBRARYCACHE 자료사전을 통해 SQL문에서 사용된 객체가 다른 사용자들에 의해 얼마나 자주 삭제되거나 변경되었는지를 분석하는 방법입니다. 주로, ANALYZE 명령어, ALTER, DROP 명령어에 의해 테이블 구조가 변경되는 경우에 발생합니다 SQL> SELECT namespace, invalidations FROM v$libraycache WHERE namespace = 'SQL AREA'; NAMESPACE INVALIDATION SQL AREA 5 INVALIDATION 컬럼의 값이 높게 출력되거나 계속적으로 증가 값을 보인다면 공유 풀 영역이 작아서 성능이 저하되고 있음을 의미합니다. 즉, 불필요한 재파싱, 재로딩 작업이 발생할 가능성이 높아지는 것 입니다. 이러한 결과에 의해 튜닝이 필요하다면 다음과 같은 파라메터 값을 높게 설정하셔야 합니다. SHARED_POOL_SIZE = [크기] 문법 SHARED_POOL_RESERVED_SIZE = [크기] SHARED_POOL_RESERVED_MIN_ALLOC = [크기] [SHARED_POOL_SIZE] 파라메트는 공유 풀 영역의 전체크기를 결정하는 파라메터입니다. 만약, V$LIBRARY 자료사전을 통해 분석된 결과값이 튜닝 기준값에 적합하지 않다면 라이브러리 캐시영역의 크기를 크게 할당해 주어야 하는데 오라클 데이터베이스에서는 이 영역만 크게 할당해 주는 파라메터는 없으며 공유 풀 영역의 크기를 크게 할당해주면 오라클 서버가 적절한 크기로 라이브러리 영역의 크기를 할당해 줍니다.
[SHARED_POOL_RESERVED_SIZE] 파라메트는 PL/SQL 블록으로 실행된 SQL문의 구문분석 정보를 저장할 때 사용되는 공유 풀 영역입니다. 일반적인 SQL문과는 달리 PL/SQL 블록들은 문장의 크기가 매우 크기 때문에 구문 분석된 결과 또한 매우 크기 마련입니다. 이러한 결과를 라이브러리 캐시영역에 저장하다 보면 연속된 메모리 공간이 없는 경우(단편화-FRAGMENTATION 현상) 분석결과가 여러 개의 조각으로 쪼개어져 저장됨으로서 단편화 현상을 더 유발시킬 수 있습니다.
결국, 이러한 단편화 현상은 데이터 검색 시 성능을 저하시키기 때문에 미리 아주 큰 PL/SQL 믈록의 구문분석 정보를 저장할 수 있는 충분한 메모리 공간을 확보한다면 이런 문제를 해결할 수 있을 것입니다. 이때 사용하는 파라메터이며 기본값은 SHARED_POOL_SIZE의 10%니며 최대값은 SHARED_POOL _SIZE 값의 1/2 입니다. 만약, 사용자의 개발환경이 PL/SQL 블록으로 개발된 애플리케이션 프로그램이 많다면 이 파라메터 값을 충분하게 설정해 주는 것이 좋습니다.
이 파라메터는 V$SHARED_POOL_RESERVED 자료사전의 REQUEST_FAILURES 컬럼의 값이 0의값이 아니거나 계속 증가값을 보일 때 높은 값을 설정해 주어야 좋은 성능을 기대할 수 있습니다. 반대로, REQUEST_FAILURES 컬럼의 값이 계속 0이면 메모리의 낭비가 초래될 수 있으므로 파라메터의 값을 낮게 설정해 주어야 합니다.
[SHARED_POOL_RECERVED_MIN_ALLOC] 파라메터는 PL/SQL 블록의 크기가 이 파라메터에 지정된 크기 이상되어야 RESERVED 영역에 저장될 수 있습니다. <잠깐>공유 풀 영역의 단편화(Fragmentation) 현상을 제거하는 방법 시스템을 사용하다 보면 메모리 영역과 디스크 영역에서 많은 읽기/쓰기 작업이 발생합니다. 제한된 공간을 계속적으로 사용하다 보면 공간에 대한 단편화(FRAGMENTATION) 현상이 발생할 수 밖에 없습니다. 문제는 단편화 현상으로 인해 효율적인 공간관리가 되지 않고 성능까지 저하되는 현상이 유발되는 것 입니다. 오라클 데이터베이스의 SGA 영역 또한 단편화 현상으로 인해 메모리 공간이 낭비되거나 SQL문의 성능저하를 유발시킬 수 도 있습니다. 문제를 해결할 수 있는 가장 효과적인 방법은 가끔 데이터베이스를 재 시작하는 방법이지만 실제 기업환경에서는 거의 불가능한 일 입니다. 다음과 같이 ALTER SYSTEM 명령어를 사용하면 데이터베이스의 재 시작없이 공유 풀 영역을 클리어(Clear) 시킬 수 있습니다.
SQL> ALTER SYSTEM SET FLUSH SHARED_POOL; 데이터 딕셔너리 캐시 영역의 튜닝 분석 오라클 데이터베이스를 설치하면 기본적으로 생성되는 테이블, 뷰, 패키지, 프로시저, 함수 등을 데이터 딕션어리(DATAT DICTIONARY)라고 합니다. 그리고, 데이터베이스를 시작(STA RTUP)하거나, SQL문을 실행하면 일부 데이터 딕션어리(V$~로 시작되는 뷰) 정보가 오라클 서버에 의해 공유 풀 영역의 데이터 딕션너리 캐시영역에 로드 됩니다.
또한, 개발자 또는 데이터베이스 관리자가 튜닝 및 관리의 목적으로 자료사전을 참조하기도 합니다. 이러한 자료사전이 읽혀질 때마다 공유 풀 영역의 데이터 딕션너리 영역에 관련정보를 로더하게 됩니다. V$~로 시작되는 일부 자료사전은 데이터베이스의 마운트 단계에서 만 질의할 수 있지만 대부분의 자료사전(DBA_, USER_, X$~)들은 데이터베이스를 오픈 단계까지 시작해야 만 질의할 수 있습니다.
그럼, 데이터 딕션너리 영역에 대한 튜닝방법에 대해서 알아보겠습니다. 사용자가 참조하는 자료사전이 질의될 때마다 그 정보를 데이터 딕션너리 영역에서 참조할 수 있다면 자료사전을 보다 빠르게 조회할 수 있을 것이고 그렇지 못하다면 자료사전을 데이터 파일로부터 읽어서 데이터 딕션너리 영역으로 로더해야 할 것입니다. 결론적으로, 디스크로부터 자료사전이 읽혀지는 것보다는 데이터 딕션너리 영역으로부터 읽혀지는 것이 성능에 유리하다는 의미입니다
다음은 자료사전을 통해 라이브러리 영역을 분석하는 방법입니다. V$ROWCACHE 자료사전을 참조하면 이 영역에 대한 튜닝 결과를 확인할 수 있습니다. SQL> SELECT sum(gets), sum(getmisses), sum(gets)/sum(getmisses) FROM v$rowcache; SUM(GETS) SUM(GETMISSES) SUM(GETS)/SUM(GETMISSES) 2126 902 2.3569 [GETS] 컬럼은 사용자가 자료사전을 질의했을 때 데이터 딕션너리 영역으로 자료를 요청했던 수를 의미합니다. 대부분의 자료사전을 빠르게 검색하기 위해서는 [GETS] 컬럼에 대한 [GETMISSES] 컬럼의 백분율이 2% 미만이어야 하고 아주 큰 자료사전 테이블에 대한 검색을 빠르게 하기 위해서는 15% 미만이어야 이 영역에 대한 성능을 기대할 수 있습니다.
만약, 이러한 조건을 만족하지 못한다면 공유 풀 영역의 크기를 더 크게 설정해야 합니다.
라이브러리 영역과 같이 이 영역 만 크게 할당해 주는 파라메터는 없으며 공유 풀 영역의 크기를 크게 할당해주면 오라클 서버가 적절한 크기로 데이터 딕션너리 영역의 크기를 할당해 줍니다. <조치사항> $ cd $HOME/dbs 2) 동일한 SQL문 작성을 위한 표준화 작업을 한다. V$LIBRARY 자료사전을 통해 개발자가 실행한 SQL문이 LIBRARY CACHE 공간에서 어떻게 저장되고 관리되는지를 자세히 알아 보았습니다. 그렇다면, 개발자가 실행하는 SQL문의 성능을 극대화 시키고 메모리 공간도 효과적으로 사용할 수 있는 방법은 없을까요 ??
첫 번째 방법이 공유 풀 영역의 크기를 충분히 할당 해 주는 것이라면 두 번째 방법은 모든 SQL문이 동일하게 작성되어 실행되게 함으로서 불필요한 PARSING과 불필요한 RE-LOADING을 피하게 하는 것입니다.
자~ 그렇다면 동일한 SQL문을 실행할 수 있는 가장 최선의 방법은 무엇일까요 ?
프로젝트를 하다 보면 다양한 개성과 창조적인 감성을 가진 인간이 만들어 내는 SQL문을 동일하게 만든다는 것은 말처럼 그리 쉬운 일은 아닐 것 입니다.
가장 최선의 방법은 모든 개발자들이 정해진 규칙에 의해 SQL문을 작성할 수 있도록 표준화를 하는 것 입니다. 일반적으로 정보 시스템을 개발하기 전에 애플리케이션 프로그래밍에 대한 "코딩 표준화", 사용자와의 인터페이스를 효과적으로 하기 위한 "화면 디자인 표준화" 등이 같은 맥락에서 이해할 수 있는 내용입니다.
우리가 이러한 표준화를 하는 궁극적인 목적은 크게 2가지로 요약할 수 있습니다.
첫 번째 목적은 약속된 프로그래밍 규칙을 통해 향후 유지 보수적인 측면을 고려한 것 입니다. 만약, 아무런 규칙없이 프로그래밍을 한다면 너무나도 다양한 유형의 프로그램들이 생성되어 자신이 개발하지 않은 프로그램 소스는 제대로 이해하지 못하는 문제로 인해 유지보수에 어려움을 겪게될 것 입니다.
두 번째 문제는 성능 문제입니다. 다양한 소스코드를 만들게 되면 프로그래밍이 어려워질 뿐 아니라 불필요한 메모리와 디스크 공간의 낭비를 초래할 수 있기 때문입니다.
다음 예제는 시스템 개발초기에 프로젝트 관리자 또는 데이터베이스 분석/설계자에 의해 동일한 SQL문을 만들어 내기 위한 표준화 작업의 일부입니다. 이러한 표준화작업은 사용자의 개발환경에 맞게 적절하게 변형하셔야 하며 새로운 내용의 추가 및 삭제가 추가적으로 필요합니다. 그럼, 지금부터 저를 따라 오세요. SQL문의 대문자 또는 소문자로 통일하십시오. 사용자의 애플리케이션 프로그램 속에는 수많은 SQL문이 저장되어 있습니다. 시스템 개발은 여러 명이 한 팀이 되어 진행되는데 프로그래머들은 각각 개성과 사고를 가진 인격체이기 때문에 어떤 약속을 해두지 않는다면 어떤 사람은 대문자로, 어떤 사람은 소문자로 SQL문을 작성할 것이고 결국 동일한 SQL문을 만들어 내지 못합니다. SQL> SELECT * FROM emp; SQL> UPDATE emp SET sal = sal 8 1.1 WHERE deptno = 10; 변수명은 SQL문, 객체명, 변수명과 구분하기 위해 소문자로 작성하십시오. 변수명은 SQL문, 객체명, 컬럼명과 구분하기 위해 소문자로 작성하십시오. SQL문의 빠른 이해와 컬럼 간의 구분을 쉽게 하기 위해 필요합니다. SQL> SELECT RESNO, HNAME INTO :ls_ResNo, :ls_HName FROM EMPTBL WHERE HNAME LIKE '홍길동'; 다른 스키마의 테이블을 호출할 때는 SCHEMA명.테이블명 으로 작성하십시오. 다른 스키마의 테이블을 호출할 때는 "Schema명.테이블명"으로 작성하십시오. 만약, 시노늄을 작성하여 사용할 때에는 시노늄 명을 결정하는 네이밍 룰(NAMING RULE)을 잘 작성하여 이름 만 봐도 이해할 수 있도록 해 주십시오. SQL> SELECT RESNO, HNAME FROM SCOTT.EMP WHERE RESNO = 1234; SQL문의 각 단어의 여백은 한 칸으로 하십시오. SQL문의 각 단어와 단어의 여백은 1칸으로 작성하십시오. 콤마(comma)는 앞 문자와는 간격을 두지 말고 뒷 문자와는 간격을 1칸으로 작성하십시오. 또한, 컬럼 리스트는 되도록 모두 한 줄에 기술하십시오. (2줄 이상일 경우는 첫줄, 첫 컬럼에 맞추어 작성하십시오.) SQL> SELECT RESNO, HNAME INTO :ls_ResNo, :ls_HName FROM EMPTBL WHERE HNAME LIKE '홍길동'; SQL문 내의 변수명은 변수 선언 기준 안에 따르며 해당 컬럼명을 접두어와 경합하여 사용하십시오. SQL문 내의 변수 명은 변수선언 기준 안에 따르며 해당 컬럼명을 접두어와 결합하여 사용하십시오. 또한, WHERE절의 비교 처리에는 변수를 사용하십시오. string gi_resno // 사원번호(G는 글로벌 변수, L은 로컬변수, // i는 정수타입, s는 문자타입) sql> SELECT RESNO, HNAME FROM EMPTBL WHERE RESNO = :ii_resno; SQL문의 SELECT, FROM, WHERE절은 각 라인의 선두에 사용하십시오. SQL> SELECT RESNO, HNAME FROM EMPTBL WHERE RESNO = :ii_resno; 자주 사용하는 SQL문을 캐싱한다. 라이브러리 캐시영역을 통해 성능을 향상시킬 수 있는 세 번째 방법은 자주 실행되는 SQL문의 구문 분석정보를 라이브러리 영역에 캐싱 해 두었다가 문장이 재실행될 때 마다 재사용하게 하는 방법입니다. 불필요한 구문 분석단계를 피할 수 있기 때문에 SQL문의 성능을 향상을 시킬 수 있습니다.
다음 내용은 라이브러리 캐시영역의 성능과 관련된 파라메터들 입니다. CURSOR_SPACE_FOR_TIME = FALSE 만약, 2명의 사용자에 의해 동일한 SQL문이 실행된다면 공유 풀 영역에 있는 구문 분석된 SQL TEXT 정보를 공유하게 될 것입니다. 그러나, PRIVATE SQL AREA 라는 영역에는 2명의 사용자가 실행한 구문 분석된 정보가 각각 저장되게 됩니다. 이 파라메터 값을 TRUE로 설정하면 PRIVATE SQL AREA에 공유 풀 영역의 구문 분석정보를 참조하는 커서가 하나라도 있으면 AGING 알고리즘에 의해 공유 풀 영역으로부터 제거되지 않고 계속 상주할 수 있도록 해 줍니다. 이 파라메터의 기본값은 FALSE 입니다. 만약, 개발자들이 실행하는 SQL문에서 같은 문장이 반복적으로 실행되는 경우가 많다면 이 파라메터를 TRUE 설정하는 것이 성능향상에 유리합니다. SESSION_CACHED_CURSORS = 0 오라클사에서 제공하는 FORMS 개발 툴 또는 C, COBOL, FORTRAN과 같은 3GL 언어로 시스템을 개발하는 경우, 하나의 조회화면에서 또 다른 조회화면으로 전환하는 프로그램을 구현하다 보면 메인 화면에서 다음 화면으로 이동할 때 메인 프로그램에서 실행되었던 SQL문의 구문 분석정보가 라이브러리 캐시영역으로부터 완전히 제거될 수가 있습니다. 서버 프로그램을 조회한 후 다시 메인 프로그램으로 돌아갔을 때 이미 실행했던 SQL문을 다시 구문 분석하게 된다면 불필요한 작업으로 인해 SQL문의 성능은 저하될 수 있을 것 입니다. 이 파라메터는 하나의 세션에서 캐싱할 수 있는 커서의 수를 지정할 수 있습니다. 이 파라메터의 기본값은 0 입니다 CLOSE_CACHED_OPEN_CURSORS = FALSE 개발자가 실행한 SQL문의 트랜잭션이 COMMIT문을 만나는 순간 관련된 구문 분석정보도 라이브러리 캐시영역으로부터 함께 제거하는 파라메터입니다. 이 파라메터의 기본값은 FALSE 입니다 OPEN_CURSORS = 300 하나의 세션에서 동시에 오픈할 수 있는 커서의 수를 지정할 때 사용합니다. 커서를 너무 많이 오픈하게 되면 그 만큼 많은 커서 정보가 라이브러리 캐시영역에 로더되어야 하기 때문에 성능에 도움이 되지 않습니다. 이 파라메터의 기본값은 오라클 데이터베이스 버전에 따라 틀리며 9i인 경우 300 입니다.
다음은 INIT<SID>.ORA 파일에 파라메터들을 등록하는 방법입니다. $ cd $HOME/dbs $ vi init<SID>.ora ….. CURSOR_SPACE_FOR_TIME = TRUE SESSION_CACHED_CURSORS = 10 CLOSE_CACHED_OPEN_CURSORS = TRUE OPEN_CURSORS = 500 :wq! 자주 사용하는 PL/SQL/ 블록을 캐싱한다. 프로젝트를 수행하다 보면 아주 복잡한 스토어드 프로시저, 함수, 패키지, 트리거 등을 생성하게 됩니다. 하지만, 이런 PL/SQL 블록들은 너무 커서 실행할 때 마다 라이브러리 캐시영역에 로더 되었다가 다시 제거되는 현상이 반복적으로 발생할 수 밖에 없습니다. 이런 문제가 자주 발생하면 라이브러리 캐시영역에는 단편화 현상이 발생하게 되고 데이터베이스를 사용하는 전체 사용자들의 성능이 저하되게 됩니다.
오라클 사에서는 자주 실행되는 PL/SQL 블록, 시퀀스 등을 라이브러리 영역에 캐싱해 둘 수 있도록 DBMS_SHARED_POOL 패키지를 제공합니다. 다음 예제를 따라 해 보십시오.
먼저, 라이브러리 영역에 캐싱되어 있는 PL/SQL 블록의 정보를 참조하는 자료사전은 V$DB_OBJECT_CACHE 입니다. SQL> > select name, type, kept from v$db_object_cache where type in ( 'PACKAGE','PROCEDURE', 'TRIGGER', 'PACKAGEBODY'); NAME TYPE KEPT ----------------------------- <- 캐싱된 PL/SQL 블록 정보가 없습니다. 일단, 애플리케이션에서 자주 실행되는 스토어드 프로시저를 생성한 후 공유 풀 영역에 로더 시켜 보겠습니다. 라이브러리 캐시영역에 로더시킬 때는 DBMS_SHARED_KEEP 패키지를 사용하고 제거할 때는 DBMS_SHARED_UNKEEP 패키지를 사용합니다. SQL> CONNECT scott/tiger SQL> CREATE OR REPLACE PROCEDURE check_sawon (v_emp_on) IN emp.empno%TYPE IS BEGIN DELETE FROM emp WHERE empno = v_emp_no; END check_sawon; / SQL> execute DBMS_SHARED_POOL.KEEP('SCOTT.CHECK_SAWON'); <- CHECK_SAWON 프로시저를 공유 풀 영역에 상주합니다. SQL> select type, name from v$db_object_cache where type in ('PACKAGE','PROCEDURE','TRIGGER', 'PACKAGE BODY') END check_sawon; NAME TYPE KEPT ----------------------------------------------------- CHECK_SAWON PROCEDURE Y <-KEPT = Y의 의미는 CHECK_SAWON 프로시저가 캐싱되어 있음을 의미합니다 SQL> exit STATS.SQL 스크립트를 실행하면 위와 같이 ANALYZE 명령어에 의해 분석된 테이블의 구조를 확인할 수 있습니다. 앞에서도 언급했듯이 튜닝을 잘 하기 위해서는 데이터베이스의 구조를 잘 알아야 합니다.
$ vi init<SID>.ora
…..
SHARED_POOL_SIZE = 32000000 ß 이전 값보다 더 큰 값으로 변경
:wq!
PINS 컬럼에 대한 RELOADS 컬럼의 백분율이 1% 미만일 때 좋은 성능을 기대할 수 있습니다.
[GETMISSES] 컬럼은 자료요청을 했지만 데이터 딕션너리 영역으로부터 자료를 얻지 못했던 수를 의미합니다.
$ vi init<SID>.ora
…..
SHARED_POOL_SIZE = 32000000 ß 이전 값보다 더 큰 값으로 변경
:wq!
v$db_object_cache 자료사전을 조회한 후, 그 중 하나를 공유 풀 영역에 상주 시켜봅시다.
[오라클]2-1단계 데이터 파일 (0) | 2012.12.19 |
---|---|
[오라클]1-5단계 래치와 경합 (0) | 2012.12.19 |
[오라클]1-4단계 자바풀 영역 (0) | 2012.12.19 |
[오라클]1-3단계 로그버퍼 영역 (0) | 2012.12.19 |
[오라클]1-2단계 버퍼캐쉬 영역 (0) | 2012.12.19 |