|
블록 익스텐트 세그먼트 |
데이터베이스 작업으로 인해 데이터가 증가하여 할당된 공간을 초과할 때, 오라클은 세그먼트를 확장합니다. INSERT나 UPDATE 문을 실행시킬 때 세그먼트를 확장하여 동적으로 확장이 이루어지게 되면 성능은 감소합니다. 서버가 여유 공간을 찾고 데이터 딕셔너리에 익스텐트를 추가하기 위하여 여러 순환적(recursive) SQL문을 실행하기 때문입니다.
동적인 확장을 피하기 위하여 다음을 수행합니다:
공간을 쉽게 관리하기 위하여, DBA는 적절한 크기의 세그먼트와 익스텐트로 객체를 생성합니다. 일반적으로, 작은 익스텐트 보다는 큰 익스텐트가 선호됩니다.
크기가 큰 익스텐트의 장점
크기가 큰 익스텐트의 단점
큰 익스텐트를 적게 할당할 것인가 아니면 작은 익스텐트를 많이 할당할 것인가를 결정할 때에는, 테이블의 증가와 사용에 대한 계획에 맞추어 각각의 이점과 결함을 고려해야 합니다.
데이터베이스 튜닝 목표 중의 하나는 액세스되는 블록의 수를 최소화하는 것입니다. 이 목표를 달성하기 위하여, 개발자는 애플리케이션과 SQL 문을 튜닝하고, DBA는 다음을 통해 블록 액세스를 감소시킵니다:
불행하게도, DBA에게 마지막 2개의 목표는 서로 상충됩니다. 즉, 많은 데이터를 블록으로 압축시키면, 행 이전이 증가하기 때문입니다
블록 크기의 특성은 다음과 같습니다:
선택된 블록 크기는 성능에 영향을 미칩니다. 일반적인 Guideline은 다음과 같습니다:
작은 오라클 블록
장점
단점
큰 오라클 블록
장점
단점
데이터베이스 블록의 크기를 재조정하는데 추가 메모리가 없을 경우, DB_BLOCK_BUFFERS를
재설정할 필요가 있습니다. 이것은 캐쉬 적중율에 영향을 미칠 것입니다.
기술적 주의사항
|
PCTFREE 파라미터 DELETE 또는 UPDATE 문을 실행시키면, 오라클은 문장을 처리하고, 사용되고 있는
블록 공간이 현재 PCTUSED 보다 작은가를 검사합니다. 작을 경우, 블록은 free list의 처음 부분으로 등록됩니다.
트랜잭션이 커밋될 때, 블록의 여유 공간은 다른 트랜잭션에 이용될 수 있습니다(3). DML과 PCTFREE 및 PCTUSED
데이터 블록의 여유 공간을 연속으로 압축하는 것으로 인해 데이터베이스 시스템의 성능이 감소하기 때문에, 오라클은 위와 같은 경우에만 이러한 압축을 수행합니다. |
Guidelines
다음과 같은 두 가지 상황에서는, 테이블 행의 데이터가 너무 크기 때문에 단일 데이터 블록에 다 들어가지 않을 것입니다.
이전 및 연쇄화는 다음과 같이 성능에 부정적인 영향을 미칩니다:
이전 현상은 PCTFREE가 너무 낮게 설정 되었을 때 발생합니다. 갱신 작업을 수행하는데 충분한 여유 메모리가 없기 때문입니다. 이전 현상을 피하기 위해서는, 갱신되는 모든 테이블은 블록 공간이 갱신 작업에 충분하도록 PCTFREE를 설정해야 합니다.
ANALYZE …COMPUTE STATISTICS
ANALYZE 문의 COMPUTE
STATISTICS option을 사용하면 테이블이나 클러스터 내에 이전 및 연쇄화 된 행이 존재하는지 알 수 있습니다. 이 명령어는
이전 및 연쇄화 된 행의 수를 세어 DBA_TABLES의 CHAIN_CNT열에 기록합니다.
NUM_ROWS열은 분석된 테이블 또는
클러스터에 저장된 총 행수를 가집니다.이전된 행을 제거해야 할 지를 결정하기 위해서 전체 행 수에 대한 이전 및 연쇄화
된 행의 비율을
계산하십시오.
Table Fetch Continued Row Statistic
또한 V$SYSSTAT이나
report.txt의 Table Fetch Continued Row 통계정보를 확인하여 이전 및 연결 된 행이 있는지를 알 수
있습니다.
Guidelines
PCTFREE를 증가시켜, 이전되는 행을 피하십시오. 블록에 이용할 수 있는 더 많은 여유 공간이 있다면, 행은 증가하는데
필요한 공간을 갖게 될 것입니다. 또한 많은 삭제가 있는 테이블이나 인덱스를 재구성(재생성) 할 수 있습니다.
ANALYZE ... LIST CHAINED
ROW
LIST CHAINED ROWS 옵션과 함께 ANALYZE 명령을 사용하여, 테이블 또는 클러스터에서
이전되었거나 연결된 행을 식별할 수 있습니다. 이 명령은 이전되었거나 연결된 각 행에 대한 정보를 수집하여 특정 출력 테이블에 놓습니다. 연결된
행을 포함하는 테이블을 생성하기 위해서는, UTLCHAIN.SQL 스크립트를 실행시키십시오.
create table
CHAINED_ROWS(
owner_name varchar2(30),
table_name
varchar2(30),
cluster_name
varchar2(30),
partition_name
varchar2(30),
head_rowid
rowid,
analyze_timestamp date);
이 테이블을 수동으로 생성할 경우, 테이블의 열 이름, 데이터 유형, 크기는 CHAINED_ROWS 테이블의
것과 같아야 합니다.
다음의 SQL*Plus 스크립트를 사용하여 이전된 행을 삭제할 수
있습니다:
/*
Get the name of the table with migrated rows */
accept
table_name prompt ‘Enter the name of the table with migrated
rows:’
/* Clean up from last execution
*/
set echo off
drop table
migrated_rows;
drop table chained_rows;
/* Create the CHAINED_ROWS
table */
@?/rdbms/admin/utlchain
set
echo on
spool fix_mig
/* List the
chained & migrated rows */
analyze table
&table_name list chained rows;
/* Copy the
chained/migrated rows to another table */
create table
migrated_rows as
select
orig.*
from
&table_name orig, chained_rows
cr
where
orig.rowid =
cr.head_rowid;
and cr.table_name = upper
(‘&table_name’);
/* Delete the
chained/migrated rows from the orignial table */
delete
from &table_name
where rowid in
( select head_rowid from chained_rows);
/* Copy the
chained/migrated rows back into the original table
*/
insert into &table_name select * from
migrated_rows;
spool off
이 스크립트를 사용할 때에는, 행이 삭제 시 위반하게 될 외부키(foreign key) 제약조건을 출력할 필요가 있습니다.
최고 수위 표시 위의 공간은 다음 명령을 사용하여 테이블 레벨에서 이용할 수
있습니다:
ALTER
TABLE <table_name> DEALLOCATE UNUSED…
전체 테이블 스캔 시, 오라클은 최고 수위 표시 아래의 모든 블록을 읽습니다. 최고 수위 표시 위의 빈 블록은 공간을 낭비할
수는 있지만, 성능을 저하시키지는 않습니다. 그러나, 최고 수위 표시 아래의 사용된 블록 이하는 성능을 저하시킬 것입니다.
통계를 수집하고 데이터 딕셔너리 저장장소에 저장하기 위하여, 테이블, 인덱스, 클러스터의 저장장소 특성을 분석할 수
있습니다. 이들 통계를 사용하여 테이블이나 인덱스가 사용되지 않은 공간을 갖고 있는지의 여부를 결정할 수
있습니다.
DBA_TABLES 뷰를 질의하여 결과 통계 자료를 보십시오.
|
열 |
설명 |
|
NUM_ROWS |
테이블의 행 수 |
|
BLOCKS |
최고 수위 표시 아래의 블록 수 |
|
EMPTY_BLOCKS |
최고 수위 표시 위의 블록 수 |
|
AVG_SPACE |
최고 수위 표시 아래 블록의 평균 여유공간 |
|
AVG_ROW_LEN |
행 오버헤드를 포함한, 평균 행 길이 |
|
CHAIN_CNT |
테이블의 이전된 또는 연결된 행 수 |
EMPTY_BLOCKS는 이전에는 완전 사용되었지만 현재는 비워있는 블록을 나타내는 것이 아니라, 아직 사용되지 않은 블록을 나타냅니다.
기술적 주의사항
오라클은 SAMPLE 절이 생략될 경우에는 1064 행을 샘플로 하고, 데이터의 반 이상이 SAMPLE 수치에 의해
지정되었을 경우에는 ESTIMATE가 아니라 COMPUTE를 사용합니다.
또한 지원되는 위의 패키지를 사용하여 세그먼트의 공간 사용에 관한 정보를 얻을 수 있습니다. 이 패키지에는 2개의 프로시저가 포함되어 있습니다:
이들 프로시저는 catproc.sql에 의해 실행되는 dbmsutil.sql 스크립트에 의해 생성되어
문서화됩니다. 이 패키지를 실행시킬 때, FREE_LIST_GROUP_ID 값을 제공해야 합니다. Oracle Parallel Server를
사용하지 않을 경우, 1을 사용하십시오.
이 스크립트는 사용자에게 테이블 소유자와 테이블명에 관한 정보를 제공하고,
DBMS_SPACE.UNUSED_SPACE를 실행시키며, 공간 관련 통계를 출력합니다.
Declare
owner
varchar2(30);
name
varchar2(30)
seq_type
varchar2(30)
tblock
number;
uBlock
number;
ubyte
number;
lue_fid
number;
lue_bid
number;
lublock
number;
BEGIN
dbms_space.unused_space
(‘&owner’, ‘&table_name’,
‘TABLE’,
tblock, tbyte,
ublock, ubyte, lue_fid, lue_bid,
lublock);
dbms_output.put_line (‘Total blocks allocated to
table = ‘
||
to_char(tblock));
dbms_output.put_line (‘Total blocks
allocated to table =
‘
||
to_char(tbyte));
dbms_output.put_line (‘Unused blocks(above
HWM) =
‘
||
to_char(ublock));
dbms_output.put_line (‘Unused
blocks(above HWM) =
‘
||
to_char(ubyte));
dbms_output.put_line (‘Last extent used
file id =
‘
||
to_char(lue_fid));
dbms_output.put_line (‘Last extent used
beginning block id =
‘
||
to_char(lue_bid));
dbms_output.put_line (‘Last extent block
in last extent =
‘
||
to_char(lublock));
END;
휘발성 테이블에 대한 인덱스 또한 성능 문제를 나타낼 수 있습니다.
데이터
블록에서, 오라클은 삭제된 행을 삽입된 행으로 교체합니다. 그러나, 인덱스 블록에서는, 엔트리들을 순서대로 정열합니다. 값은 동일한 범위의 다른
값들과 함께 적당한 블록으로 갑니다.
많은 애플리케이션은 오름차순 인덱스 순서로 삽입하고 이전 값을 삭제합니다. 그러나, 블록이
한 엔트리만을 포함하더라도, 이 블록은 유지되어야 합니다. 이러한 경우에, 인덱스를 규칙적으로 재구축해야 할 필요가 있을
것입니다.
인덱스 블록의 모든 엔트리를 삭제할 경우, 오라클은 이 블록을 free list에 다시 놓습니다.
다음 명령을 사용하여 인덱스에 의해 사용되는 공간을 감시할 수
있습니다.
SQL> ANALYZE
INDEX index_name VALIDATE STRUCTURE;
그런 다음
INDEX_STATS 뷰를 질의하십시오:
|
열 |
설명 |
|
LF_ROWS |
현재 인텍스에 있는 값의 수 |
|
LF_ROWS_LEN |
모든 값의 길이의 바이트 합 |
|
DEL_LF_ROWS |
인덱스에서 삭제된 값의 수 |
|
DEL_LF_ROWS_LEN |
모든 삭제된 값의 길이 |
주의:
INDEX_STATS 뷰는 가장 마지막에 분석된 인덱스를 보여줍니다. 만인 동일 사용자로 다른 세션으로 접속하였다면 뷰는 그 뷰를 질의하는
세션에서 분석된 인덱스를 보여 줍니다.
인덱스 재구성(REBUILD)
애플리케이션과 우선순위에 따라 다르겠지만, 삭제된 엔트리가 현재 엔트리의 20% 또는 그 이상을 나타낼 경우 재구축할
것을 결정할 것입니다. 위의 질의를 사용하여 비율을 찾을 수 있습니다. ALTER INDEX REBUILD 문을 사용하여, 기존 인덱스를
재구성하거나 압축하든지, 또는 저장장소 특성을 변경하십시오. REBUILD 문은 기존 인덱스를 사용하여 새로운 인덱스를 구축합니다.
STORAGE(익스텐트 할당에 대해), TABLESPACE(인덱스를 새로운 테이블스페이스로 이동시키기 위해), INITRANS(초기 엔트리의
수를 변경하기 위해)와 같은 모든 인덱스 저장장소 명령어가 지원됩니다.또한, 인덱스를 구축할 때, 다음 키워드를 사용하여 재구축하는데 소요되는
시간을 감소시킬 수 있습니다:
UNRECOVERATBLE과 NOLOGGING은 동일하지 않습니다.
주의: Oracle8의 초기버전에서는 UNRECOVERABLE 옵션을 사용할 수
있었지만, 그것은 NOLOGGING 옵션으로 대체되었습니다.
UNRECOVERABLE 절처럼 사용하기 위하여,
NOLOGGING 옵션으로 객체를 생성한 후 ALTER 명령으로 LOGGING으로 변경하십시오. RECOVERABLE 절처럼 사용하기 위하여,
LOGGING 옵션으로 객체를 생성하십시오.
ALTER INDEX REBUILD는 일반적으로 빠른 전체 스캔 기능을 이용하기 때문에 인덱스를 해제하고 재생성하는 것보다 훨씬 더 빠릅니다. 따라서, ALTER INDEX REBUILD는 복수 블록 I/O를 사용하여 모든 인덱스 블록을 읽은 다음 분기 블록은 삭제합니다. 이러한 접근법의 더 나은 장점은 재구축 작업이 진행 되는 동안에도 이전의 인덱스를 질의(DML에 대해서는 안됨)에 여전히 사용할 수 있다는 것입니다.
기술적 주의사항
ANALYZE 명령의 변형으로 인덱스가 손상될 경우, 인덱스를
재구축해야 합니다.
|
문맥 |
참조 |
|
초기화 파라메터 |
None |
|
동적인 성능 뷰 |
V$SYSSTAT |
|
데이터 딕셔너리 뷰 |
USER_, ALL_, DBA_CLUSTERS |
|
명령어 |
ALTER/CREATE
INDEX/TABLE/CLUSTER |
|
패키지된 프로시저 및 함수 |
DBMS_SPACE |
|
스크립트 |
dbmsutil.sql, utlchain.sql |
|
진단팩 애플리케이션 |
Performance Manager |