태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

Partition Statistics를 손쉽게 Copy하기

오라클 2009.02.12 17:12
통계 정보 관리와 관련해서 가장 많이 접하는 질문 중 하나는 다음과 같다.
  • 우리 회사에서는 주기적으로 Partition(대부분 Range Partition)을 추가하고 Data를 로드한다.
  • Data양이 워낙 많기 때문에 통계 정보를 수집하는 것이 대단히 부담스럽다.
  • 통계 정보를 수집하지 않고, 새로 만들어진 Partition에 대해서만 통계 정보를 수동으로 만들어 주는 방법은 없을까?


이런 상황을 많이 접한 분들이라면 아마 나름대로의 해결책을 가지고 있을 것이다.

Oracle 10.2.0.4부터는 dbms_stats.copy_table_stats를 이용하면 이 고민이 매우 손쉽게 해결된다. 이 방법을 사용할 수 없으면 dbms_stats.set_xxx_stats 프로시저들을 이용해서 수동으로 통계 정보를 지정하는 방법도 사용 가는하다. 하지만 역시 새로운 버전에서 제공되는 편리한 기능을 사용할 수 있다면 최선이다.

아래 영문 블로그에서 이들 방법의 자세한 사용법을 확인할 수 있다.

How to copy partition stats? - We got easier way!



신고
Trackback 0 : Comments 7
  1. DONi 2009.11.23 15:14 신고 Modify/Delete Reply

    안녕하세요...

    통계 복사후에 날짜 속성 컬럼값의 통계값에 LOW_VALUE, HIGH_VALUE에 대해 추가작업이

    필요하지 않을까요?

    DBMS_STATS.SET_COLUMN_STATS procedure 관련된 추가보정 작업이 필요할 것 같습니다.

    • 욱짜 2009.11.23 15:31 신고 Modify/Delete

      dbms_stats.copy_table_stats는 low_value, high_value까지 자동으로 설정합니다(그렇지 않다면 너무 쓰기 불편할 겁니다)

      단, low_value와 high_value값을 설정하지 않은 버그도 보고되고 있으므로 반드시 확인 후 사용할 필요는 있습니다.

  2. DONi 2009.11.23 16:58 신고 Modify/Delete Reply

    음..제가 작업한 후에 확인 해보았습니다만,(version 10.2.0.4)

    EXEC DBMS_STATS.COPY_TABLE_STATS(OWNNAME => 'owner', TABNAME => 'partitioned_table', SRCPARTNAME => 'P200902', DSTPARTNAME => 'P200904');

    SELECT TABLE_NAME, PARTITION_NAME, COLUMN_NAME, NUM_DISTINCT,
    UTL_RAW.CAST_TO_VARCHAR2(LOW_VALUE) AS LOW_VALUE,
    UTL_RAW.CAST_TO_VARCHAR2(HIGH_VALUE) AS HIGH_VALUE
    --,DENSITY, NUM_NULLS, SAMPLE_SIZE, LAST_ANALYZED
    FROM DBA_PART_COL_STATISTICS
    WHERE OWNER = 'owner' AND TABLE_NAME = 'partitioned_table' AND PARTITION_NAME = 'P200903';

    SELECT TABLE_NAME, PARTITION_NAME, COLUMN_NAME, NUM_DISTINCT,
    UTL_RAW.CAST_TO_VARCHAR2(LOW_VALUE) AS LOW_VALUE,
    UTL_RAW.CAST_TO_VARCHAR2(HIGH_VALUE) AS HIGH_VALUE
    --,DENSITY, NUM_NULLS, SAMPLE_SIZE, LAST_ANALYZED
    FROM DBA_PART_COL_STATISTICS
    WHERE OWNER = 'owner' AND TABLE_NAME = 'partitioned_table' AND PARTITION_NAME = 'P200904';

    파티션 P200904의 파티션 기준 컬럼을 포함한 다른 날짜 컬럼 역시 P200903의 값과 동일합니다.

    자동으로 HIGH, LOW_VALUE를 보정하는 것은 11g 에도 없는 것 같습니다만,,,

  3. DONi 2009.11.23 17:00 신고 Modify/Delete Reply

    script에 오류가 있습니다...
    다음의 스크립트가 맞습니다. 죄송...(3월에서 4월로 복사...)


    EXEC DBMS_STATS.COPY_TABLE_STATS(OWNNAME => 'owner', TABNAME => 'partitioned_table', SRCPARTNAME => 'P200903', DSTPARTNAME => 'P200904');

    SELECT TABLE_NAME, PARTITION_NAME, COLUMN_NAME, NUM_DISTINCT,
    UTL_RAW.CAST_TO_VARCHAR2(LOW_VALUE) AS LOW_VALUE,
    UTL_RAW.CAST_TO_VARCHAR2(HIGH_VALUE) AS HIGH_VALUE
    --,DENSITY, NUM_NULLS, SAMPLE_SIZE, LAST_ANALYZED
    FROM DBA_PART_COL_STATISTICS
    WHERE OWNER = 'owner' AND TABLE_NAME = 'partitioned_table' AND PARTITION_NAME = 'P200903';

    SELECT TABLE_NAME, PARTITION_NAME, COLUMN_NAME, NUM_DISTINCT,
    UTL_RAW.CAST_TO_VARCHAR2(LOW_VALUE) AS LOW_VALUE,
    UTL_RAW.CAST_TO_VARCHAR2(HIGH_VALUE) AS HIGH_VALUE
    --,DENSITY, NUM_NULLS, SAMPLE_SIZE, LAST_ANALYZED
    FROM DBA_PART_COL_STATISTICS
    WHERE OWNER = 'owner' AND TABLE_NAME = 'partitioned_table' AND PARTITION_NAME = 'P200904';

    • 욱짜 2009.11.23 21:11 신고 Modify/Delete

      Oracle Manual에는 다음과 같이 기술되어 있습니다.
      http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_stats.htm#BABDDBGH

      <quote>
      It sets the high bound partitioning value as the maximum value of the first partitioning column and high bound partitioning value of the previous partition as the minimum value of the first partitioning column for a range partitioned table. It finds the maximum and minimum from the list of values for the list partitioned table. It also sets the normalized maximum and minimum values. If the destination partition is the first partition then minimum values are equal to maximum values. If the statistics for source are not available then nothing is copied.
      </quote>

      10.2.0.4에 High Value, Low Value가 변경되지 않은 버그가 있습니다. 메타링크 문서 8318020를 참조하세요.

  4. DONi 2009.11.25 14:02 신고 Modify/Delete Reply

    Oracle 11g에서는 파티션 기준 컬럼은 자동적으로 보정이 되는군요(x86 11.1.0.7.0)

    그외의 컬럼은 물론 소스파티션의 값으로 복사됩니다.

    10g에서는 어쩔 수 없이 수작업으로 보정하는 수 밖엔 없네요...

    다음의 파티션 기준 컬럼에 대한 예제 스크립트입니다.

    DECLARE
    V_SREC DBMS_STATS.STATREC;
    V_ArrVals DBMS_STATS.CHARARRAY;
    BEGIN

    V_SREC.epc := 2;
    V_SREC.eavs := null;
    V_SREC.bkvals := DBMS_STATS.NUMARRAY(2.60592219238428E35, 2.60592219238428E35);
    V_ArrVals := DBMS_STATS.CHARARRAY('20090401', '20090430');

    DBMS_STATS.PREPARE_COLUMN_VALUES(V_SREC, V_ArrVals);

    DBMS_STATS.SET_COLUMN_STATS
    (
    OWNNAME=>'owner명',
    TABNAME=>'테이블명',
    COLNAME=>'SALEDATE',
    PARTNAME=>'P200904',
    DISTCNT=>30,
    DENSITY=>0.0357142857142857,
    NULLCNT=>0,
    AVGCLEN=>9,
    SREC=>V_SREC
    );
    END;
    /

    • 욱짜 2009.11.25 14:54 신고 Modify/Delete

      이런 기본적인 기능에서조차 버그가 있다는 것이 안타까울 뿐이죠. 해당 버그(버그번호는 8719831이네요)에 대한 패치를 설치하는 것이 가장 좋을 거 같습니다. 자세한 내용은 아래 블로그 포스트를 참조하세요.

      http://optimizermagic.blogspot.com/2009/02/maintaining-statistics-on-large.html

Write a comment

티스토리 툴바