Oracle8 Administrator's Guide Release 8.0 A58397-01 |
|
This chapter describes various aspects of managing partitioned tables and indexes, and includes the following sections:
Note: Before attempting to create a partitioned table or index or perform maintenance operations on any partition, review the information about partitioning in Oracle8 Concepts. |
Today's enterprises frequently run mission-critical databases containing upwards of several hundred gigabytes and, in many cases, several terabytes of data. These enterprises are challenged by the support and maintenance requirements of very large databases (VLDB), and must devise methods to meet those challenges.
One way to meet VLDB demands is to create and use partitioned tables and indexes. A partitioned table or index has been divided into a number of pieces, or partitions, which have the same logical attributes. For example, all partitions in a table share the same column and constraint definitions, and all partitions in an index share the same index options. Each partition is stored in a separate segment and can have different physical attributes (such as PCTFREE, PCTUSED, INITRANS, MAXTRANS, TABLESPACE, and STORAGE).
Although you are not required to keep each table or index partition in a separate tablespace, it is to your advantage to do so. Storing partitions in separate tablespaces can:
See Also: For more detailed information on partitioning concepts and benefits, see Oracle8 Concepts.
This section describes how to create table and index partitions.
Creating partitions is very similar to creating a table or index: you must use the CREATE TABLE statement with the PARTITION CLAUSE. Also, you must specify the tablespace name for each partition when you have partitions in different tablespaces.
The following example shows a CREATE TABLE statement that contains 4 partitions, one for each quarter's worth of sales. A row with SALE_YEAR=1994, SALE_MONTH=7, and SALE_DAY=18 has the partitioning key (1994, 7, 18), and is in the third partition, in the tablespace TSC. A row with SALE_YEAR=1994, SALE_MONTH=7, and SALE_DAY=1 has the partitioning key (1994, 7, 1), and also is in the third partition.
CREATE TABLE sales Splitting PartitionsSplitting Partitions ( invoice_no NUMBER, sale_year INT NOT NULL, sale_month INT NOT NULL, sale_day INT NOT NULL ) PARTITION BY RANGE ( sale_year, sale_month, sale_day) ( PARTITION sales_q1 VALUES LESS THAN ( 1994, 04, 01 ) TABLESPACE tsa, PARTITION sales_q2 VALUES LESS THAN ( 1994, 07, 01 ) TABLESPACE tsb, PARTITION sales_q3 VALUES LESS THAN ( 1994, 10, 01 ) TABLESPACE tsc, PARTITION sales q4 VALUES LESS THAN ( 1995, 01, 01 ) TABLESPACE tsd);
See Also: For more information about the CREATE TABLE statement and PARTITION clause, see Oracle8 SQL Reference.
For information about partition keys, partition names, bounds, and equi-partitioned tables and indexes, see Oracle8 Concepts.
This section describes how to accomplish specific partition maintenance operations, including:
See Also: For information about the SQL syntax for DDL statements, see Oracle8 SQL Reference.
For information about the catalog views that describe partitioned tables and indexes, and the partitions of a partitioned table or index, see Oracle8 Reference.
For information about Import, Export and partitions, see Oracle8 Utilities.
For general information about partitioning, see Oracle8 Concepts.
You can use the MOVE PARTITION clause of the ALTER TABLE statement to:
Typically, you can change the physical storage attributes of a partition in a single step via a ALTER TABLE/INDEX MODIFY PARTITION statement. However, there are some physical attributes, such as TABLESPACE, that you cannot modify via MODIFY PARTITION. In these cases you can use the MOVE PARTITION clause.
You can use the MOVE PARTITION clause to move a partition. For example, a DBA wishes to move the most active partition to a tablespace that resides on its own disk (in order to balance I/O). The DBA can issue the following statement:
ALTER TABLE parts MOVE PARTITION depot2 TABLESPACE ts094 NOLOGGING;
This statement always drops the partition's old segment and creates a new segment, even if you don't specify a new tablespace.
When the partition you are moving contains data, MOVE PARTITION marks the matching partition in each local index, and all global index partitions as unusable. You must rebuild these index partitions after issuing MOVE PARTITION.
Some operations, such as MOVE PARTITION and DROP TABLE PARTITION, mark all partitions of a global index unusable. You can rebuild the entire index by rebuilding each partition individually using the ALTER INDEX REBUILD PARTITION statement. You can perform these rebuilds concurrently.
You can also simply drop the index and re-create it.
This section describes how to add new partitions to a partitioned table and how partitions are added to local indexes.
You can use the ALTER TABLE ADD PARTITION statement to add a new partition to the "high" end (the point after the last existing partition). If you wish to add a partition at the beginning or in the middle of a table, or if the partition bound on the highest partition is MAXVALUE, you should instead use the SPLIT PARTITION statement.
When the partition bound on the highest partition is anything other than MAXVALUE, you can add a partition using the ALTER TABLE ADD PARTITION statement.
For example, a DBA has a table, SALES, which contains data for the current month in addition to the previous 12 months. On January 1, 1996, the DBA adds a partition for January:
ALTER TABLE sales ADD PARTITION jan96 VALUES LESS THAN ( '960201' ) TABLESPACE tsx;
When there are local indexes defined on the table and you issue the ALTER TABLE ... ADD PARTITION statement, a matching partition is also added to each local index. Since Oracle assigns names and default physical storage attributes to the new index partitions, you may wish to rename or alter them after the ADD operation is complete.
You cannot explicitly add a partition to a local index. Instead, new partitions are added to local indexes only when you add a partition to the underlying table.
You cannot add a partition to a global index because the highest partition always has a partition bound of MAXVALUE. If you wish to add a new highest partition, use the ALTER INDEX SPLIT PARTITION statement.
This section describes how to use the ALTER TABLE DROP PARTITION statement to drop table and index partitions and their data.
You can use the ALTER TABLE DROP PARTITION statement to drop table partitions.
If there are local indexes defined for the table, ALTER TABLE DROP PARTITION also drops the matching partition from each local index.
If, however, the partition contains data and global indexes, use either of the following methods to drop the table partition:
ALTER TABLE sales DROP PARTITION dec94; ALTER INDEX sales_area_ix REBUILD sal1;This method is most appropriate for large tables where the partition being dropped contains a significant percentage of the total data in the table.
Note: You can substantially reduce the amount of logging by setting the NOLOGGING attribute (using ALTER TABLE...MODIFY PARTITION...NOLOGGING) for the partition before deleting all of its rows. |
For example, a DBA wishes to drop the first partition, which has a partition bound of 10000. The DBA issues the following statements:
DELETE FROM sales WHERE TRANSID < 10000; ALTER TABLE sales DROP PARTITION dec94;This method is most appropriate for small tables, or for large tables when the partition being dropped contains a small percentage of the total data in the table.
If a partition contains data and has referential integrity constraints, choose either of the following methods to drop the table partition:
ALTER TABLE sales DISABLE CONSTRAINT dname_sales1; ALTER TABLE sales DROP PARTITTION dec94; ALTER TABLE sales ENABLE CONSTRAINT dname_sales1;This method is most appropriate for large tables where the partition being dropped contains a significant percentage of the total data in the table.
This method is most appropriate for small tables or for large tables when the partition being dropped contains a small percentage of the total data in the table.
You cannot explicitly drop a partition from a local index. Instead, local index partitions are dropped only when you drop a partition from the underlying table.
If a global index partition is empty, you can explicitly drop it by issuing the ALTER INDEX DROP PARTITION statement.
If a global index partition contains data, dropping the partition causes the next highest partition to be marked unusable. For example, a DBA wishes to drop the index partition P1 and P2 is the next highest partition. The DBA must issue the following statements:
ALTER INDEX npr DROP PARTITION P1; ALTER INDEX npr REBUILD PARTITION P2;
Use the ALTER TABLE TRUNCATE PARTITION statement when you wish to remove all rows from a table partition. You cannot truncate an index partition; however, the ALTER TABLE TRUNCATE PARTITION statement truncates the matching partition in each local index.
You can use the ALTER TABLE TRUNCATE PARTITION statement to remove all rows from a table partition with or without reclaiming space. If there are local indexes defined for this table, ALTER TABLE TRUNCATE PARTITION also truncates the matching partition from each local index.
If, however, the partition contains data and global indexes, use either of the following methods to truncate the table partition:
ALTER TABLE sales TRUNCATE PARTITION dec94; ALTER INDEX sales_area_ix REBUILD sal1;This method is most appropriate for large tables where the partition being truncated contains a significant percentage of the total data in the table.
This method is most appropriate for small tables, or for large tables when the partition being truncated contains a small percentage of the total data in the table.
If a partition contains data and has referential integrity constraints, choose either of the following methods to truncate the table partition:
ALTER TABLE sales DISABLE CONSTRAINT dname_sales1; ALTER TABLE sales TRUNCATE PARTITTION dec94; ALTER TABLE sales ENABLE CONSTRAINT dname_sales1;This method is most appropriate for large tables where the partition being truncated contains a significant percentage of the total data in the table.
Note: You can substantially reduce the amount of logging by setting the NOLOGGING attribute (using ALTER TABLE...MODIFY PARTITION...NOLOGGING) for the partition before deleting all of its rows. |
This method is most appropriate for small tables, or for large tables when the partition being truncated contains a small percentage of the total data in the table.
This form of ALTER TABLE/INDEX divides a partition into two partitions. You can use the SPLIT PARTITION clause when a partition becomes too large and causes backup, recovery or maintenance operations to take a long time. You can also use the SPLIT PARTITION clause to redistribute the I/O load.
You can split a table partition by issuing the ALTER TABLE SPLIT PARTITION statement. If there are local indexes defined on the table, this statement also splits the matching partition in each local index. Because Oracle assigns system-generated names and default storage attributes to the new index partitions, you may wish to rename or alter these index partitions after splitting them.
If the partition you are splitting contains data, the ALTER TABLE SPLIT PARTITION statement marks the matching partitions (there are two) in each local index, as well as all global index partitions, as unusable. You must rebuild these index partitions after issuing the ALTER TABLE SPLIT PARTITION statement.
In this scenario "fee_katy" is a partition in the table "VET_cats," which has a local index, JAF1. There is also a global index, VET on the table. VET contains two partitions, VET_parta, and VET_partb.
To split the partition "fee_katy", and rebuild the index partitions, the DBA issues the following statements:
ALTER TABLE vet_cats SPLIT PARTITION fee_katy at (100) INTO ( PARTITION fee_katy1 ..., PARTITION fee_katy2 ...); ALTER INDEX JAF1 REBUILD PARTITION SYS_P00067; ALTER INDEX JAF1 REBUILD PARTITION SYS_P00068; ALTER INDEX VET REBUILD PARTITION VET_parta; ALTER INDEX VET REBUILD PARTITION VET_partb;
Also, unless JAF1 already contained partitions fee_katy1 and fee_katy2, names assigned to local index partitions produced by this split will match those of corresponding base table partitions.
You cannot explicitly split a partition in a local index. A local index partition is split only when you split a partition in the underlying table.
You can issue the ALTER INDEX SPLIT PARTITION statement to split a partition in a global index if the partition is empty.
The following statement splits the index partition containing data, QUON1:
ALTER INDEX quon1 SPLIT PARTITION canada AT VALUES LESS THAN ( 100 ) INTO PARTITION canada1 ..., PARTITION canada2 ...); ALTER INDEX quon1 REBUILD PARTITION canada1; ALTER INDEX quon1 REBUILD PARTITION canada2;
While there is no explicit MERGE statement, you can merge a partition using either the DROP PARTITION or EXCHANGE PARTITION clauses.
You can use either of the following strategies to merge table partitions.
If you have data in partition OSU1 and no global indexes or referential integrity constraints on the table, OH, you can merge table partition OSU1 into the next highest partition, OSU2.
ALTER TABLE OH DROP PARTITION OSU1;
ALTER TABLE OH DROP PARTITION OSU1;
The only way to merge partitions in a local index is to merge partitions in the underlying table.
If the index partition BUCKS is empty, you can merge global index partition BUCKS into the next highest partition, GOOSU, by issuing the following statement:
ALTER INDEX BUCKEYES DROP PARTITION BUCKS;
If the index partition BUCKS contains data, issue the following statements:
ALTER INDEX BUCKEYES DROP PARTITION BUCKS; ALTER INDEX BUCKEYES REBUILD PARTITION GOOSU;
While the first statement marks partition GOOSU unusable, the second makes it valid again.
You can convert a partition into a non-partitioned table, and a table into a partition of a partitioned table by exchanging their data (and index) segments. Exchanging table partitions is most useful when you have an application using non-partitioned tables which you want to convert to partitions of a partitioned table. For example, you may already have partition views that you wish to migrate into partitioned tables.
This scenario describes how merge two adjacent table partitions. Suppose you have to merge two partitions, FEB95 and MAR95, of the SALES table by moving the data from the FEB95 partition into the MAR95 partition.
CREATE TABLE sales_feb95 (...) TABLESPACE ts_temp STORAGE (INITIAL 2);
Now the SALES_FEB95 table placeholder segment is attached to the FEB95 partition.
Using the extended table name here is more efficient. Instead of attempting to compute the partition to which a row belongs, Oracle verifies that it belongs to the specified partition.
See Also: For more information about deferring index maintenance, see the ALTER SESSION SET SKIP_UNUSABLE_INDEXES statement in Oracle8 SQL Reference.
This scenario describes how to convert a partition view (also called "manual partition") into a partitioned table. The partition view is defined as follows:
CREATE VIEW accounts SELECT * FROM accounts_jan95 UNION ALL SELECT * FROM accounts_feb95 UNION ALL ... SELECT * FROM accounts_dec95;
CREATE TABLE accounts_new (...) TABLESPACE ts_temp STORAGE (INITIAL 2) PARTITION BY RANGE (opening_date) (PARTITION jan95 VALUES LESS THAN ('950201'), ... PARTITION dec95 VALUES LESS THAN ('960101'));
So now the placeholder data segments associated with the NOV95 and DEC95 partitions have been exchanged with the data segments associated with the ACCOUNTS_NOV95 and ACCOUNTS_DEC95 tables.
See Also: For more information about the syntax and usage of the statements in this section, see Oracle8 SQL Reference.
Some operations, such as ALTER TABLE DROP PARTITION, mark all partitions of a global index unusable. You can rebuild global index partitions in two ways:
An historical table describes the business transactions of an enterprise over intervals of time. Historical tables can be base tables, which contain base information; for example, sales, checks, orders. Historical tables can also be rollup tables, which contain summary information derived from the base information via operations such as GROUP BY, AVERAGE, or COUNT.
The time interval in an historical table is a rolling window; DBAs periodically delete sets of rows that describe the oldest transaction, and in turn allocate space for sets of rows that describe the most recent transaction. For example, at the close of business on April 30, 1995 the DBA deletes the rows (and supporting index entries) that describe transactions from April, 1994, and allocates space for the April, 1995 transactions.
Now consider a specific example. You have a table, ORDER, which contains 13 months of transactions: a year of historical data in addition to orders for the current month. There is one partition for each month; the partitions are named ORDER_yymm.
The ORDER table contains two local indexes, ORDER_IX_ONUM, which is a local, prefixed, unique index on the order number, and ORDER_IX_SUPP, which is a local, non-prefixed index on the supplier number. The local index partitions are named with suffixes that match the underlying table. There is also a global unique index, ORDER_IX_CUST, for the customer name; ORDER_IX_CUST contains three partitions, one for each third of the alphabet. So on October 31, 1994, change the time window on ORDER as follows:
ALTER TABLESPACE ORDER_9310 BEGIN BACKUP; ALTER TABLESPACE ORDER_9310 END BACKUP;
Ordinarily, Oracle acquires sufficient locks to ensure that no operation (DML, DDL, utility) interferes with an individual DDL statement, such as ALTER TABLE DROP PARTITION. However, if the partition maintenance operation requires several steps, it is the DBA's responsibility to ensure that applications (or other maintenance operations) do not interfere with the multi-step operation in progress.
For example, there are referential integrity constraints on the table ORDER, and you do not wish to disable them to drop the partition. Instead, you can replace Step 2 from the previous section with the following:
DELETE FROM ORDER WHERE ODATE < TO_DATE( 01-NOV-93 ); ALTER TABLE ORDER DROP PARTITION ORDER_9310;
You can ensure that no one inserts new rows into ORDER between the DELETE step and the DROP PARTITION steps by revoking access privileges from an APPLICATION role, which is used in all applications. You can also bring down all user-level applications during a well-defined batch window each night or weekend.