블로그 이미지
redkite

카테고리

분류 전체보기 (291)
00.SI프로젝트 산출물 (0)
00.센터 운영 문서 (0)
01.DBMS ============.. (0)
01.오라클 (117)
001.DB 관리 (19)
002.DB 마이그레이션 (8)
003.DB 백업 및 복구 (20)
004.DB 보안 (8)
005.DB 설치 (7)
006.DB 스크립트 (0)
007.DB Knowledge Bas.. (38)
008.DB 통계 및 공간 관리 (3)
009.DB Trouble Shoot.. (14)
010.교육자료 (0)
999.테스트 (0)
01.MS-SQL (15)
01.MySQL (30)
01.PostgreSql (0)
01.DB튜닝 (28)
====================.. (0)
02.SERVER ==========.. (0)
02.서버-공통 (11)
02.서버-Linux (58)
02.서버-Unix (12)
02.서버-Windows (2)
====================.. (0)
03.APPLICATION =====.. (11)
====================.. (0)
04.ETC =============.. (0)
04.보안 (5)
====================.. (0)
05.개인자료 (1)
06.캠핑관련 (0)
07.OA관련 (1)
Total
Today
Yesterday

달력

« » 2024.5
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

공지사항

최근에 올라온 글

'01.오라클/008.DB 통계 및 공간 관리'에 해당되는 글 3건

  1. 2012.12.19 [오라클]SHRINK SPACE 관리
  2. 2012.12.19 [오라클]DBMS STAT PACK 이용
  3. 2012.12.19 [오라클]통계정보 갱신 방법

SHRINK SPACE는 오라클10g부터 지원하는 기능으로,

세그먼트의 데이터 조각모음(ONLINE Reorg. 효과) 기능.

 

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

1. SHRINK 작업을 수행하기 위한 주요 환경 및 주의할 점
-----------------------------------------------------

   1) 오라클 10g 이상(Init.ora parameter 'Compatible' must be >=10.0)
   2) 세그먼트 관리방식이 반드시 ASSM(Auto Segment Space Managed) Tablespace이어야 함
   3) 약 20여건씩 INSERT/DELETE하고 COMMIT하는 방식으로 SHRINK함
   4) 개별 ROW 또는 데이터 BLOCK에 대한 LOCK(ENQUEUE)이 사용
   5) FBI(Function-Based Index)를 SHRINK하는 경우
      오류 발생하므로 FBI를 DROP한 다음 작업하고
      SHRINK작업이 완료된 후 다시 생성
   6) DML TRIGGER를 발생시키지 않음(ROWID based TRIGGER는 작업 전에 DISABLED 필요)
   7) DML 작업은 세그먼트 SHRINK 중 수행 가능하나, parallel DML을 수행될 수 없음 
   8) 세그먼트를 SHRINK 시키는 특정 단계(HWM을 조정하는 단계)에서 세그먼트에

      exclusive 모드로 짧은 시간동안 LOCK(TM)이 걸림

 

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

2. SHRINK 작업 방법 (순서 1]~6])
-----------------------------------------------------

   1] SHRINK 대상 테이블 분석 및 조회
      (NUM_ROWS에 비해 사용하는 BLOCKS가 과다하면 SHRINK필요)
      SQL> connect / as sysdba

      SQL> EXECUTE DBMS_UTILITY.ANALYZE_SCHEMA('소유자', 'COMPUTE');

      SQL> SELECT OWNER,     TABLE_NAME,   NUM_ROWS,
                  BLOCKS,    EMPTY_BLOCKS, AVG_SPACE,
                  CHAIN_CNT, AVG_ROW_LEN
             FROM DBA_TABLES
            WHERE OWNER = '소유자'
              AND EMPTY_BLOCKS / (BLOCKS + EMPTY_BLOCKS) < 0.1
              AND (BLOCKS + EMPTY_BLOCKS) > 0
            ORDER BY BLOCKS DESC;

 

      [참고] DBMS_SPACE.VERIFY_SHRINK_CANDIDATE

 

   2] 대상 테이블 및 관련 인덱스 NOLOGGING 설정

      SQL> connect 소유자/암호
      SQL> ALTER TABLE 테이블명 NOLOGGING;
      SQL> ALTER TABLE 인덱스명 NOLOGGING;

 

   3] 대상 테이블의 ROW MOVEMENT 기능 활성화
      (데이터의 조각모음으로 ROWID가 변경되므로 ENABLE ROW MOVEMENT)
      SQL> ALTER TABLE 테이블명 ENABLE ROW MOVEMENT;

 

   4] 필요한 작업을 선택적으로 작업
      4-1) 테이블만 SHRINK하고 HWM(High Water Mark)는 SHRINK하지 않음
           SQL> ALTER TABLE 테이블명 SHRINK SPACE COMPACT;

 

      4-2) 테이블과 HWM(High Water Mark)를 SHRINK
           (HWM SHRINK 시 TM 락 발생)
           SQL> ALTER TABLE 테이블명 SHRINK SPACE;

 

      4-3) 테이블과 테이블의 HWM을 SHRINK
           SQL> ALTER TABLE 테이블명 SHRINK SPACE COMPACT;
           SQL> ALTER TABLE 테이블명 SHRINK SPACE;

 

      4-4) 인덱스와 인덱스의 HWM을 SHRINK
           (ROWID가 변경되지 않으므로 ENABLE ROW MOVEMENT 불필요)
           SQL> ALTER INDEX 인덱스명 SHRINK SPACE COMPACT;
           SQL> ALTER INDEX 인덱스명 SHRINK SPACE;

 

      4-5) 테이블 및 관련된 인덱스를 모두 SHRINK
           SQL> ALTER TABLE 테이블명 SHRINK SPACE CASCADE COMPACT;
           SQL> ALTER TABLE 테이블명 SHRINK SPACE CASCADE;

 

   5] Row movement 비활성화
      SQL> ALTER TABLE 테이블명 DISABLE ROW MOVEMENT;

 

   6] 대상 테이블 및 관련 인덱스 LOGGING 설정
      SQL> ALTER TABLE 테이블명 LOGGING;
      SQL> ALTER TABLE 인덱스명 LOGGING;

 

   ※ M-View 형태의 테이블을 SHRINK
      on-commit materialized view와 연관된 세그먼트는 SHRINK 시킬 수 없음
      rowid에 기반을 둔 materialized view에 대해서는 refresh 또는 rebuild를 수행 필요
      SQL> ALTER TABLE M-View명 SHRINK SPACE COMPACT;
      SQL> ALTER TABLE M-View명 SHRINK SPACE;

Posted by redkite
, |

0002. DBMS_STATS pack 이용

dbms_stats.gather_schema_stats 프로시저를 이용해서 통계 정보를 수집하는 경우 수행 시간이 너무 많이 걸린다는 불만이 종종 있다. 이런 현상은 대부분 다음과 같은 경우에 발생한다.

- 특정 테이블들의 크기가 매우 크다.
- 일부 큰 테이블들은 Partitioning이 되어 있다.

즉 큰 테이블들이 있고 더구나 Partitioning까지 되어 있으니(Global/Partiton Statistics모두 수집해야 하므로) 그만큼 통계 정보 수집에 시간이 걸리기 마련이다. 하지만 Oracle 10g에서는 estimate_percent 파라미터와 method_opt 파라미터의 값이 Oracle에 의해 적절하게 판단되어 통계 정보 생성 시간을 최적화한다. 그렇다면 왜 필요 이상 많은 시간이 걸리는 경우가 발생하는가?

이것은 이 두 파라미터에 다음과 같은 결함이 있기 때문이다.

- estimate_percent 파라미터의 값이 AUTO이다. 즉, Oracle이 테이블의 크기에 따라 적절한 샘플 크기를 선택한다는 의미이다. 대부분의 경우 Oracle은 테이블의 크기에 따라 적절한 값을 찾지만, 간혹 아주 큰 테이블에 대해 100%의 값을 사용하는 경우가 있다.
- method_opt 파라미터의 기본값이 FOR ALL COLUMNS SIZE AUTO이다. 즉 모든 컬럼에 대해 통계정보를 수집하면 히스토그램의 생성 여부는 Oracle이 판단한다. 대부분의 경우 Oracle은 적절한 히스토그램 버킷 크기를 할당하지만, 간혹 불필요하게(가령 Unique Key에 대해) 히스토그램을 생성하는 경우가 있다.

위와 같은 상황이 발생하면 예상보다 지나치게 많은 시간이 걸리게 되는 셈이다.

이런 상황을 해소할 수 있는 방법이 있을까? 가령 다음과 같이 하면...?

dbms_stats.gather_schema_stats(estimate_percent=>10, method_opt=>'FOR ALL INDEXED COLUMNS SIZE 1');

물론 위의 방법으로 수행 시간 문제는 해결하겠지만, 좋은 방법은 될 수 없다. 만일 크기가 작은 테이블들이 있다면 샘플 크기가 작으면 왜곡된 통계 정보가 수집될 수 있다. 만일 특정 테이블에 대해서는 모든 컬럼(ALL COLUMNS)에 대해 통계 정보를 수집해야 한다면? 또는 특정 테이블의 특정 컬럼에 대해서는 히스토그램 크기를 주고 싶다면?

그렇다고 테이블 레벨로 일일이 dbms_stats.gather_table_stats를 호출하는 것은 너무나 지겨운 일이다.

그래서 보통 다음과 같은 트릭을 종종 사용한다.(편의상 정확한 문법은 생략)

-- 특정 테이블 통계 정보 변경을 막음
dbms_stats.lock_table_stats(user, 'TABLE1');

exec dbms_stats.gather_schema_stats(ownname=>'ORANGE', ESTIMATE_PERCENT=> 10, BLOCK_SAMPLE=>TRUE, DEGREE=> 8, CASCADE=>TRUE);

-- 스키마 레벨로 통계 정보 수집
dbms_stats.gather_schema_stats(user);

-- 통계 정보 활성화 후 이 테이블만 다시 통계 정보 수집
dbms_stats.unlock_table_stats(user, 'TABLE1');
dbms_stats.gather_table_stats(user,'TABLE', estimate_percent=>10, method_opt=>'FOR ALL INDEXED COLUMNS SIZE AUTO');

begin

dbms_stats.gather_table_stats(ownname => 'PS_MOM', tabname => 'ETL_JOB_LOG_TBL', estimate_percent=>10)

end;

/

begin

dbms_stats.gather_index_stats(ownname => 'PS_MOM', indname => 'IDX_ETL_LOG_ID');

end;

/
위와 같이 하면 Schema 레벨로 대부분의 테이블에 대해 통계 정보를 수집한 후 특정 문제가 되는 테이블에 대해서만 별도로 통계 정보를 수집할 수 있다.

지저분한 트릭같지만 매우 유용한 방법이다.

Oracle 11g에서는 "Preference"라는 새로운 개념을 통해 위와 같은 불편을 일시에 해소하고 있다. Oracle 11g에서라면 다음과 같이 훨씬 직관적이고 깔끔한 방법을 쓸 수 있다.

-- 아래와 같이 한번만 설정
dbms_stats.set_table_prefs(user,'TABLE1', 'ESTIMATE_PERCENT', '10');
dbms_stats.set_table_prefs(user,'TABLE1','METHOD_OPT', 'FOR ALL INDEXED COLUMNS SIZE AUTO');

-- Schema 레벨에서 통계 정보 수집
dbms_stats.gather_schema_stats(user);

즉, 특정 테이블별로 Preference(선호도)를 저장할 수 있어서 10g에서와 같은 부자연스러운 트릭은 불필요한 것이다. 11g에서 가장 마음에 드는 New Feature중 하나이다.

Posted by redkite
, |

오라클을 통해 작업할

insert시점에서 정상적으로 인덱싱이 되지 않는 경우가 발생한다.

특히 결합인덱스를 많이 사용하고 있는 경우 발생될 확률이 높다.

 

이런경우 오라클의 Analyzed 통해서 해결이 가능하고

어느정도의 실행속도를 향상 시킬 수있다.

(실제 오라클사에서도 3개월에 한번씩은 Analyze 실행하라 권고하고 있다.)

 

[Analyzed 확인 방법]

select table_name, num_rows, to_char(last_analyzed, 'yyyymmdd') from user_tables

select index_name, num_rows, to_char(last_analyzed, 'yyyymmdd') from user_indexes

 

ex) select table_name, num_rows, to_char(last_analyzed, 'yyyymmdd') from user_tables;

TABLE_NAME NUM_ROWS TO_CHAR(
------------------------------ ---------- --------
ABS_TYPE 38
20040101

ANNIVERS 183 20040101
APPRFLDRHISTORY 570
20040101
APPRFOLDER 16885
20040101
APPRFOLDER_ERR 3670
20040101
APPRFORM 359
20040101
.
.
.
USR_INFO_ADMIN 0
20040101
VAR_DEPT_INFO 0
20040101
VIEW_TYPE 0
20040101
WASTEBOX 0
20040101
ZIP_CODE 44195
20040101

252 rows selected.

 

참고 : desc user_tables 에서 보통 num_rows 로도 확인 가능

 

 

[특정 Table Analyze 하는 방법]

 

analyze table document compute statistics

ex) DOCUMENT Table Analyze

 

analyze index xpkdocbox compute statistics

ex) XPKDOCBOX Index Analyze

 

[전체 Table Analyze 하는 간단한 방법]

 

1. vi analyze_all.sql
select 'analyze table || table_name || estimate statistics;' from user_tables

 

2. @analyze_all.sql

 

3. set heading off
set echo off
set feedback off
set pagesize 300 (line
300 미만일 경우)
spool analyze_table.sql
/
spool off

 

4. vi analyze_table.sql
필요없는 Line 제거 정리

 

5. @analyze_table.sql

 


[
전체 Index Analyze 하는 간단한 방법]

 

 

1. vi analyze_all.sql
select 'analyze '||object_type||' ps_mom.'||object_name||' compute statistics; '

from dba_objects

where owner = 'PS_MOM'

and object_type in('TABLE','INDEX')

/

 

2. @analyze_all.sql

 

3. set heading off
set echo off
set feedback off
set pagesize 300 (line
300 미만일 경우)
spool analyze_index.sql
/
spool off

 

4. vi analyze_index.sql
필요없는 Line 제거 정리

 

5. @analyze_index.sql

'01.오라클 > 008.DB 통계 및 공간 관리' 카테고리의 다른 글

[오라클]SHRINK SPACE 관리  (0) 2012.12.19
[오라클]DBMS STAT PACK 이용  (0) 2012.12.19
Posted by redkite
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함