Oracle/Administration2019. 7. 26. 11:16

파티션 통계정보를 복사해보고, low_value, high_value 값을 직접 설정해보자.


테스트를 위해 아래와 같이 테이블을 생성하자.

-- 1
DROP TABLE t1 PURGE;

CREATE TABLE t1 (c1 NUMBER, c2 DATE)
PARTITION BY RANGE (c2) (
    PARTITION p1 VALUES LESS THAN (DATE '2019-02-01')
  , PARTITION p2 VALUES LESS THAN (DATE '2019-03-01')
  , PARTITION p3 VALUES LESS THAN (MAXVALUE));

INSERT INTO t1 VALUES (1, DATE '2019-01-01');
INSERT INTO t1 VALUES (2, DATE '2019-01-31');
COMMIT;

EXEC DBMS_STATS.GATHER_TABLE_STATS ('TUNA', 'T1');

low_value, high_value 값을 조회하기 위해 아래와 같이 함수를 생성하자.

-- 2
CREATE OR REPLACE FUNCTION f1 (i_rawval IN RAW)
    RETURN DATE
IS
    l_resval DATE;
BEGIN
    DBMS_STATS.CONVERT_RAW_VALUE (i_rawval, l_resval);
    RETURN l_resval;
END f1;
/

아래는 파티션 칼럼 통계 정보의 low_value, high_value 값을 조회한 결과다.

-- 3
SELECT partition_name, f1 (low_value) AS low_value, f1 (high_value) AS high_value
  FROM user_part_col_statistics
 WHERE table_name = 'T1'
   AND column_name = 'C2';

PARTITION_NAME LOW_VALUE           HIGH_VALUE
-------------- ------------------- -------------------
P1             2019-01-01 00:00:00 2019-01-31 00:00:00
P2
P3

3 행이 선택되었습니다.

DBMS_STATS.COPY_TABLE_STATS 프로시저로 아래와 같이 파티션 통계 정보를 복사하자.

-- 4
EXEC DBMS_STATS.COPY_TABLE_STATS ('TUNA', 'T1', 'P1', 'P2');
EXEC DBMS_STATS.COPY_TABLE_STATS ('TUNA', 'T1', 'P1', 'P3');

파티션 칼럼 통계 정보를 다시 조회해보면 MAXVALUE의 low_value, high_value 값이 제대로 복사되지 않은 것을 확인할 수 있다.

-- 5
SELECT partition_name, f1 (low_value) AS low_value, f1 (high_value) AS high_value
  FROM user_part_col_statistics
 WHERE table_name = 'T1'
   AND column_name = 'C2';

-- 11.2
PARTITION_NAME LOW_VALUE           HIGH_VALUE
-------------- ------------------- -------------------
P1             2019-01-01 00:00:00 2019-01-31 00:00:00
P2             2019-02-01 00:00:00 2019-03-01 00:00:00
P3             2019-01-01 00:00:00 2019-01-31 00:00:00 -- !

3 행이 선택되었습니다.

-- 12.1
PARTITION_NAME LOW_VALUE           HIGH_VALUE
-------------- ------------------- -------------------
P1             2019-01-01 00:00:00 2019-01-31 00:00:00
P2             2019-02-01 00:00:00 2019-03-01 00:00:00
P3             2019-03-01 00:00:00 2019-03-01 00:00:00 -- !

3 행이 선택되었습니다.

low_value, high_value 값을 설정하기 위해 아래와 같이 프로시저를 생성하자.
-- 6
CREATE OR REPLACE PROCEDURE prc_set_column_value (
    i_ownname       IN    VARCHAR2
  , i_tabname       IN    VARCHAR2
  , i_colname       IN    VARCHAR2
  , i_partname      IN    VARCHAR2 DEFAULT NULL
  , i_low_value     IN    DATE
  , i_high_value    IN    DATE
)
IS
    l_distcnt    NUMBER;
    l_density    NUMBER;
    l_nullcnt    NUMBER;
    l_avgclen    NUMBER;
    l_srec       DBMS_STATS.STATREC;
    l_array      DBMS_STATS.DATEARRAY := DBMS_STATS.DATEARRAY();
BEGIN
    DBMS_STATS.GET_COLUMN_STATS (
        ownname  => i_ownname
      , tabname  => i_tabname
      , colname  => i_colname
      , partname => i_partname
      , distcnt  => l_distcnt
      , density  => l_density
      , nullcnt  => l_nullcnt
      , avgclen  => l_avgclen
      , srec     => l_srec
    );

    l_array.EXTEND; l_array(1) := i_low_value;
    l_array.EXTEND; l_array(2) := i_high_value;

    l_srec.bkvals.DELETE;
    l_srec.bkvals.EXTEND; l_srec.bkvals(1) := 0;
    l_srec.bkvals.EXTEND; l_srec.bkvals(2) := 1;
    l_srec.epc := 2;

    DBMS_STATS.PREPARE_COLUMN_VALUES (l_srec, l_array);

    DBMS_STATS.SET_COLUMN_STATS (
        ownname  => i_ownname
      , tabname  => i_tabname
      , colname  => i_colname
      , partname => i_partname
      , distcnt  => l_distcnt
      , density  => l_density
      , nullcnt  => l_nullcnt
      , avgclen  => l_avgclen
      , srec     => l_srec
    );
END;
/

프로시저로 아래와 같이 low_value, high_value 값을 설정하자.

-- 7
EXEC prc_set_column_value ('TUNA', 'T1', 'C2', 'P2', DATE '2019-02-01', DATE '2019-02-28');
EXEC prc_set_column_value ('TUNA', 'T1', 'C2', 'P3', DATE '2019-03-01', DATE '2019-12-31');

파티션 칼럼 통계 정보를 다시 조회해보면 low_value, high_value 값이 설정된 것을 확인할 수 있다. 버킷이 2개인 히스토그램을 설정했기 때문에 히스토그램이 없는 것으로 표시된다.

-- 8
SELECT partition_name, f1 (low_value) AS low_value, f1 (high_value) AS high_value, histogram
  FROM user_part_col_statistics
 WHERE table_name = 'T1'
   AND column_name = 'C2';

PARTITION_NAME LOW_VALUE           HIGH_VALUE          HISTOGRAM
-------------- ------------------- ------------------- ---------
P1             2019-01-01 00:00:00 2019-01-31 00:00:00 NONE
P2             2019-02-01 00:00:00 2019-02-28 00:00:00 NONE
P3             2019-03-01 00:00:00 2019-12-31 00:00:00 NONE

3 행이 선택되었습니다.

아래는 파티션 히스토그램을 조회한 결과다.
-- 9
SELECT partition_name, bucket_number, endpoint_value
  FROM user_part_histograms
 WHERE table_name = 'T1'
   AND column_name = 'C2';
   
PARTITION_NAME BUCKET_NUMBER ENDPOINT_VALUE
-------------- ------------- --------------
P1                         0        2458485
P1                         1        2458515
P2                         0        2458516
P2                         1        2458543
P3                         0        2458544
P3                         1        2458849

6 행이 선택되었습니다.


'Oracle > Administration' 카테고리의 다른 글

Partitioned External 테이블  (0) 2019.08.22
인덱스 명명 규칙  (0) 2019.08.19
CLOB #5 - ENABLE STORAGE IN ROW  (0) 2019.02.09
Covered 인덱스와 인덱스 브랜치 블록  (0) 2019.01.06
CHAR vs VARCHAR2  (0) 2019.01.01
Posted by 정희락_