The COPY_TABLE_STATS procedure copies the statistics from the source partition (or sub-partition) to the target partition (or sub-partition).
Applicability
This topic applies only to OceanBase Database Enterprise Edition. OceanBase Database Community Edition provides only the MySQL mode.
Syntax
DBMS_STATS.COPY_TABLE_STATS (
ownname VARCHAR2,
tabname VARCHAR2,
srcpartname VARCHAR2,
dstpartname VARCHAR2,
scale_factor VARCHAR2,
flags NUMBER DEFAULT NULL,
force BOOLEAN DEFAULT FALSE);
Parameters
| Parameter | Description |
|---|---|
| ownname | Specifies the schema (user) name of the source and target partitions (or sub-partitions). |
| tabname | Specifies the name of the table corresponding to the source and target partitions (or sub-partitions). |
| srcpartname | Specifies the source partition (or sub-partition) from which to copy the statistics. |
| dtspartname | Specifies the target partition (or sub-partition) to receive the statistics. |
| scale_factor | Proportionally adjusts the values of statistical properties such as nblks (block count) and nrows (row count) when copying to the target partition (or sub-partition). |
| flags | Generally, users do not need to set this parameter. |
| force | The default value is FALSE. If set to TRUE, the copy operation of the statistics will continue even if the target partition (or sub-partition) is currently in a locked state. |
Exceptions
| Error Code | Description |
|---|---|
| ORA-20000 | Indicates that the partition name is invalid. |
| ORA-20001 | Indicates that the types for the source and target partitions are different. |
Considerations
The procedure updates the minimum and maximum values in the target partition as follows:
If the partition type is HASH, the minimum and maximum values in the target partition are the same as those in the source partition.
If the partition type is LIST, the behavior depends on the settings of the target partition:
If the target partition is the DEFAULT partition:
- The minimum value of the target partition is set to the minimum value of the source partition.
- The maximum value of the target partition is set to the maximum value of the source partition.
If the target partition is a NOT DEFAULT partition:
- The minimum value of the target partition is set to the minimum value in the value list describing the target partition.
- The maximum value of the target partition is set to the maximum value in the value list describing the target partition.
If the partition type is RANGE:
If the target partition is the first partition:
If the upper boundary of the target partition is
MAXVALUE, then:- The target partition and the source partition are the same, and there is no need to copy or update the minimum and maximum values. Therefore, they do not need to be set.
If the upper boundary of the target partition is not
MAXVALUE, then:- The minimum and maximum values of the target partition will both be set to the upper boundary of the target partition.
If the target partition is not the first partition:
If the target partition is a single column partition key:
If the source partition has only one value that is equal to the lower boundary of the source partition and the upper boundary of the target partition is not
MAXVALUE, then the minimum and maximum values of the target partition are both set to the lower boundary of the target partition.Otherwise:
- If the upper boundary of the target partition is
MAXVALUE, then both the maximum and minimum values are set to the lower boundary of the target partition (that is, the upper boundary of the previous partition). - If the upper boundary of the target partition is not
MAXVALUE, then the maximum value is set to the upper boundary of the target partition, and the minimum value is set to the lower boundary of the target partition.
- If the upper boundary of the target partition is
If the target partition is a multi-column partition key:
If the source partition has only one value that is equal to the lower boundary of the source partition, then the maximum and minimum values of the target partition are both set to the lower boundary of the target partition.
Otherwise, for the current column C, it follows the rules mentioned earlier, and for the subsequent columns Cx:
- If Cx-1 is the same as
MAXVALUEbefore the target partition, then the maximum value of the target partition is set to the upper boundary of the target partition. - Otherwise, the maximum value of the target partition is set to the greater value of the upper limit of the target partition and the maximum value of the source partition column.
- If Cx-1 is the same as
Examples
The following example demonstrates how to create a HASH partitioned table test_copy_tbl1 and the related statistical operations.
(Optional) If a table named
test_copy_tbl1exists, execute the following statement to drop it.DROP TABLE test_copy_tbl1;Execute the following statement to create a table named
test_copy_tbl1with two integer columnscol1andcol2, and to partition the table using the HASH function based on col1, with four partitions:p1,p2,p3, andp4.CREATE TABLE test_copy_tbl1(col1 INT, col2 INT) PARTITION BY HASH(col1) (PARTITION p1, PARTITION p2, PARTITION p3, PARTITION p4);Execute the following statement to insert 10 rows of data into the
test_copy_tbl1table, with thecol1column ranging from 1 to 10, and thecol2column ranging from 2 to 11.INSERT INTO test_copy_tbl1 SELECT level, level + 1 FROM dual CONNECT BY LEVEL <= 10;The result is as follows:
Query OK, 10 rows affected (0.060 sec) Records: 10 Duplicates: 0 Warnings: 0Execute the following statement to call the
gather_table_statsprocedure from theDBMS_STATSpackage to collect statistics for theP1partition of the table namedtest_copy_tbl1. Themethod_optparameter specifies a histogram size of 32 buckets for all columns.CALL dbms_stats.gather_table_stats('SYS','TEST_COPY_TBL1', 'P1', method_opt=>'for all columns size 32');Execute the following statement to call the
copy_table_statsprocedure from theDBMS_STATSpackage to copy the statistics of theP1partition of thetest_copy_tbl1table to theP2partition with a scale factor of 2.CALL dbms_stats.copy_table_stats('SYS','TEST_COPY_TBL1','P1','P2', scale_factor=>2);Execute the following statement to query the
all_tab_statisticsview to retrieve the relevant statistics for all partitions of the table namedTEST_COPY_TBL1owned bySYS, including table name, partition name, number of rows, number of blocks, average row length, whether statistics are locked, whether statistics are stale, and the last analyzed time.SELECT table_name, partition_name, num_rows, blocks, avg_row_len, stattype_locked locked, stale_stats, last_analyzed FROM all_tab_statistics WHERE table_name = 'TEST_COPY_TBL1' AND owner = 'SYS';The result is as follows:
+----------------+----------------+----------+--------+-------------+--------+-------------+---------------+ | TABLE_NAME | PARTITION_NAME | NUM_ROWS | BLOCKS | AVG_ROW_LEN | LOCKED | STALE_STATS | LAST_ANALYZED | +----------------+----------------+----------+--------+-------------+--------+-------------+---------------+ | TEST_COPY_TBL1 | NULL | 10 | NULL | 40 | NULL | NO | 08-JAN-24 | | TEST_COPY_TBL1 | P1 | 2 | NULL | 40 | NULL | NO | 08-JAN-24 | | TEST_COPY_TBL1 | P2 | 4 | NULL | 40 | NULL | NO | 08-JAN-24 | | TEST_COPY_TBL1 | P3 | NULL | NULL | NULL | NULL | NULL | NULL | | TEST_COPY_TBL1 | P4 | NULL | NULL | NULL | NULL | NULL | NULL | +----------------+----------------+----------+--------+-------------+--------+-------------+---------------+ 5 rows in setFor more information about the
all_tab_statisticsview, see ALL_TAB_STATISTICS.Execute the following statement to query the
all_part_col_statisticsview to retrieve the partition column statistics for the table namedTEST_COPY_TBL1owned bySYS, and sort them by partition name and column name.SELECT * FROM all_part_col_statistics WHERE table_name = 'TEST_COPY_TBL1' AND owner = 'SYS' ORDER BY partition_name, column_name;The result is as follows:
+-------+----------------+----------------+-------------+--------------+-----------+------------+---------+-----------+-------------+-------------+---------------+--------------+------------+-------+-------------+-----------+ | OWNER | TABLE_NAME | PARTITION_NAME | COLUMN_NAME | NUM_DISTINCT | LOW_VALUE | HIGH_VALUE | DENSITY | NUM_NULLS | NUM_BUCKETS | SAMPLE_SIZE | LAST_ANALYZED | GLOBAL_STATS | USER_STATS | NOTES | AVG_COL_LEN | HISTOGRAM | +-------+----------------+----------------+-------------+--------------+-----------+------------+---------+-----------+-------------+-------------+---------------+--------------+------------+-------+-------------+-----------+ | SYS | TEST_COPY_TBL1 | P1 | COL1 | 2 | 2 | 7 | .25 | 0 | 2 | 2 | 08-JAN-24 | NO | NO | NULL | 20 | FREQUENCY | | SYS | TEST_COPY_TBL1 | P1 | COL2 | 2 | 3 | 8 | .25 | 0 | 2 | 2 | 08-JAN-24 | NO | NO | NULL | 20 | FREQUENCY | | SYS | TEST_COPY_TBL1 | P2 | COL1 | 2 | 2 | 7 | .25 | 0 | 2 | 2 | 08-JAN-24 | NO | NO | NULL | 20 | FREQUENCY | | SYS | TEST_COPY_TBL1 | P2 | COL2 | 2 | 3 | 8 | .25 | 0 | 2 | 2 | 08-JAN-24 | NO | NO | NULL | 20 | FREQUENCY | | SYS | TEST_COPY_TBL1 | P3 | COL1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | | SYS | TEST_COPY_TBL1 | P3 | COL2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | | SYS | TEST_COPY_TBL1 | P4 | COL1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | | SYS | TEST_COPY_TBL1 | P4 | COL2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | +-------+----------------+----------------+-------------+--------------+-----------+------------+---------+-----------+-------------+-------------+---------------+--------------+------------+-------+-------------+-----------+ 8 rows in setFor more information about the
all_part_col_statisticsview, see ALL_PART_COL_STATISTICS.Execute the following statement to query the
all_part_histogramsview to retrieve the partition column histogram information for the table namedTEST_COPY_TBL1owned bySYS, and sort them by partition name and column name.SELECT * FROM all_part_histograms WHERE table_name = 'TEST_COPY_TBL1' AND owner = 'SYS' ORDER BY partition_name, column_name;The result is as follows:
+-------+----------------+----------------+-------------+-----------------+----------------+-----------------------+---------------------------+-----------------------+ | OWNER | TABLE_NAME | PARTITION_NAME | COLUMN_NAME | ENDPOINT_NUMBER | ENDPOINT_VALUE | ENDPOINT_ACTUAL_VALUE | ENDPOINT_ACTUAL_VALUE_RAW | ENDPOINT_REPEAT_COUNT | +-------+----------------+----------------+-------------+-----------------+----------------+-----------------------+---------------------------+-----------------------+ | SYS | TEST_COPY_TBL1 | P1 | COL1 | 2 | NULL | 7 | 7 | 1 | | SYS | TEST_COPY_TBL1 | P1 | COL1 | 1 | NULL | 2 | 2 | 1 | | SYS | TEST_COPY_TBL1 | P1 | COL2 | 2 | NULL | 8 | 8 | 1 | | SYS | TEST_COPY_TBL1 | P1 | COL2 | 1 | NULL | 3 | 3 | 1 | | SYS | TEST_COPY_TBL1 | P2 | COL1 | 2 | NULL | 7 | 7 | 1 | | SYS | TEST_COPY_TBL1 | P2 | COL1 | 1 | NULL | 2 | 2 | 1 | | SYS | TEST_COPY_TBL1 | P2 | COL2 | 2 | NULL | 8 | 8 | 1 | | SYS | TEST_COPY_TBL1 | P2 | COL2 | 1 | NULL | 3 | 3 | 1 | +-------+----------------+----------------+-------------+-----------------+----------------+-----------------------+---------------------------+-----------------------+ 8 rows in setFor more information about the
all_part_histogramsview, see ALL_PART_HISTOGRAMS.