목차

TABLE 용량 분석

해당 Table에 할당되어 있는 크기 측정하는 방법

  1. USER_SEGMENTS 라는 Dictionary View에서 확인할 수 있다.
  2. 점유용량확인하는 방법이다.
    SELECT SEGMENT_NAME, BYTES FROM USER_SEGMENTS WHERE SEGMENT_TYPE='TABLE'

실제 사용공간 측정

  1. Table에 공간할당은 되었으나 아직 (전혀) 사용되지 않는 공간을 제외한 실제 사용되고 있는 공간을 계산하는 방법이다.
  2. 즉, High Water Mark(HWM) 아래의 공간을 측정하는 것이다.

측정방법

  1. 해당 Table을 Analyze 한다.
     analyze TABLE <table_name> compute statistics; 
  2. 해당 Table의 blocks를 구한다.
     SELECT blocks FROM dba_tables WHERE TABLE_NAME ='<table_name>'; 

    blocks + 1(segment header block) : 해당 Table 이 사용중인 database block count , HWM

  3. 위의 계산에는 사용된 후 delete에 의해 현재 완전히 비어 있는 block도 사용하고 있는 block으로 인식하므로
    완전히 비어 있는 block을 제거하기 위해서는 아래의 결과값이 나온 block만 계산하면 된다.
    1. rowid는 다음과 같이 구성되어 있다.
      object fil block row  
      ------ --- ------ ---  
      AAABPW AAF AAAAv1 AAA
    2. 따라서 아래의 Query를 실행하면 결과를 얻을 수 있다.
      HWM 아래 할당은 되었지만 완전히 비어 있는 block은 계산에서 제외되고, 조금이라도 사용된 block count만 계산된다.
      SELECT COUNT(1)
      FROM (SELECT SUBSTR(ROWID,1,15) FROM <table_name> GROUP BY SUBSTR(ROWID,1,15) );

예제

  1. costs 라는 테이블의 실제 용량을 확인해 보자.

스크립트

  1. 통계분석
    SQL> analyze TABLE costs compute statistics;
    TABLE analyzed.  
  2. block count를 알아낸다.
    SQL> select blocks from user_tables where table_name='COSTS';  
    BLOCKS  
    ----------  
    2924

    2924는 HWM 아래 block count 이다.

  3. HWM 아래에 완전히 비어있는 block count를 알아낸다.
    SQL> SELECT COUNT(1)FROM (SELECT substr(rowid,1,15) FROM costs GROUP BY substr(rowid,1,15));
    COUNT(1)  
    ----------  
    2506

    2506은 HWM 아래 block 중 사용중인 block count 이다.

정리

  1. Table의 공간(크기)이란 아래 3가지 관점에서 값이 각각 다를수 있습니다.
해당 Table에 할당된 크기 Table에 할당되었지만 사용중 또는 미사용공간 전부 포함
HWM 아래 크기 할당된 공간중에서 full table scan시 검색하는 부분까지만의 크기
즉 HWM이후 공간은 아직 한번도 사용이 안된 new block이다
HWM 아래중 완전히 비어 있는
block을 제외한 크기
delete에 의해 block전체가 비어 있는 block을 제외한 크기

생각해보자

  1. USER_SEGMENTS 의 BYTES는 실데이타 공간이 아니라 할당영역을 나타낸 것이다.
    빈 블럭도 포함이 된다
  2. 만일 UNUSED 블럭을 제외한 실제 데이타 공간을 구하려면 아래와 같이 구하면 된다.
    쿼리상의 8192는 show parameter의 DB_BLOCK_SIZE의 값이다.
    이 구문 역시 정확한 값을 얻기 위해서는 ANALYZE TABLE 을 해 주어야 한다.
    SELECT TABLE_NAME,
        GREATEST(4, CEIL(NUM_ROWS /
            ((ROUND(((8192 - (INI_TRANS * 23)) *
             ((100 - PCT_USED) /100)) / AVG_ROW_LEN)))) *
            8192)/1024/1024 TABLESIZE_MBYTES
    FROM USER_TABLES ;