Oracle9i Database Administrator's Guide
Release 1 (9.0.1)

Part Number A90117-01
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback

Go to previous page Go to next page

17
Managing Partitioned Tables and Indexes

This chapter describes various aspects of managing partitioned tables and indexes, and contains the following topics:

What Are Partitioned Tables and Indexes?

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. Partitioned tables allow your data to be broken down into smaller, more manageable pieces called partitions, or even subpartitions. Indexes can be partitioned in similar fashion. Each partition can be managed individually, and can function independently of the other partitions, thus providing a structure that can be better tuned for availability and performance.

If you are using parallel execution, partitions provide another means of parallelization. Operations on partitioned tables and indexes are performed in parallel by assigning different parallel execution servers to different partitions of the table or index.

Partitions and subpartitions of a table or index all share the same logical attributes. For example, all partitions (or subpartitions) in a table share the same column and constraint definitions, and all partitions (or subpartitions) of an index share the same index options. They can, however, have different physical attributes (such as TABLESPACE).

Although you are not required to keep each table or index partition (or subpartition) in a separate tablespace, it is to your advantage to do so. Storing partitions in separate tablespaces enables you to:

Partitioning is transparent to existing applications and standard DML statements run against partitioned tables. However, an application can be programmed to take advantage of partitioning by using partition-extended table or index names in DML.

You can use the SQL*Loader, Import, and Export utilities to load or unload data stored in partitioned tables. These utilities are all partition and subpartition aware.

See Also:

 

Partitioning Methods

There are several partitioning methods offered by Oracle:

Indexes, as well as tables, can be partitioned. A global index can only be partitioned by range, but it can be defined on any type of partitioned, or nonpartitioned, table. It usually requires more maintenance than a local index.

A local index is constructed so that it reflects the structure of the underlying table. It is equipartitioned with the underlying table, meaning that it is partitioned on the same columns as the underlying table, creates the same number of partitions or subpartitions, and gives them the same partition bounds as corresponding partitions of the underlying table. For local indexes, index partitioning is maintained automatically when partitions are affected by maintenance activity. This ensures that the index remains equipartitioned with the underlying table.

The following sections can help you decide on a partitioning method appropriate for your needs:

When to Use the Range Partitioning Method

Use range partitioning to map rows to partitions based on ranges of column values. This type of partitioning is useful when dealing with data that has logical ranges into which it can be distributed; for example, months of the year. Performance is best when the data evenly distributes across the range. If partitioning by range causes partitions to vary dramatically in size because of unequal distribution, you may want to consider one of the other methods of partitioning.

When creating range partitions, you must specify:

The example below creates a table of four partitions, one for each quarter's sales. The columns sale_year, sale_month, and sale_day are the partitioning columns, while their values constitute a specific row's partitioning key. The VALUES LESS THAN clause determines the partition bound: rows with partitioning key values that compare less than the ordered list of values specified by the clause are stored in the partition. Each partition is given a name (sales_q1, sales_q2, ...), and each partition is contained in a separate tablespace (tsa, tsb, ...).

CREATE TABLE sales
    ( 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 (1999, 04, 01) 
        TABLESPACE tsa,
      PARTITION sales_q2 VALUES LESS THAN (1999, 07, 01) 
        TABLESPACE tsb,
      PARTITION sales_q3 VALUES LESS THAN (1999, 10, 01) 
        TABLESPACE tsc,
      PARTITION sales_q4 VALUES LESS THAN (2000, 01, 01) 
        TABLESPACE tsd ); 

A row with sale_year=1999, sale_month=8, and sale_day=1 has a partitioning key of (1999, 8, 1) and would be stored in partition sales_q3.

Each partition of a range-partitioned table is stored in a separate segment.


Note:

If your enterprise has or will have databases using different character sets, use caution when partitioning on character columns, because the sort sequence of characters is not identical in all character sets. For more information, see Oracle9i Globalization and National Language Support Guide. 


When to Use the Hash Partitioning Method

Use hash partitioning if your data does not easily lend itself to range partitioning, but you would like to partition for performance and manageability reasons. Hash partitioning provides a method of evenly distributing data across a specified number of partitions. Rows are mapped into partitions based on a hash value of the partitioning key. Creating and using hash partitions gives you a highly tunable method of data placement, because you can influence availability and performance by spreading these evenly sized partitions across I/O devices (striping).

To create hash partitions you specify the following:

The following example creates a hash-partitioned table. The partitioning column is id, four partitions are created and assigned system generated names, and they are placed in four named tablespaces (gear1, gear2, ...).

CREATE TABLE scubagear
     (id NUMBER,
      name VARCHAR2 (60))
   PARTITION BY HASH (id)
   PARTITIONS 4 
   STORE IN (gear1, gear2, gear3, gear4);

Each partition of a hash-partitioned table is stored in a separate segment.

When to Use the List Partitioning Method

Use list partitioning when you require explicit control over how rows map to partitions. You can specify a list of discrete values for the partitioning column in the description for each partition. This is different from range partitioning, where a range of values is associated with a partition, and from hash partitioning, where the user has no control of the row to partition mapping.

The list partitioning method is specifically designed for modeling data distributions that follow discrete values. This cannot be easily done by range or hash partitioning because:

Further, list partitioning allows unordered and unrelated sets of data to be grouped and organized together very naturally.

Unlike the range and hash partitioning methods, multi-column partitioning is not supported for list partitioning. If a table is partitioned by list, the partitioning key can consist only of a single column of the table. Otherwise all columns that can be partitioned by the range or hash methods can be partitioned by the list partitioning method.

When creating list partitions, you must specify:

The following example creates a list-partitioned table. It creates table sales_by_region which is partitioned by region; that is, states are grouped together according to their geographical location.

CREATE TABLE sales_by_region
      (deptno number, 
       deptname varchar2(20),
       quarterly_sales number(10, 2),
       state varchar2(2))
   PARTITION BY LIST (state)
      (PARTITION q1_northwest VALUES ('OR', 'WA'),
       PARTITION q1_southwest VALUES ('AZ', 'UT', 'NM'),
       PARTITION q1_northeast VALUES  ('NY', 'VM', 'NJ'),
       PARTITION q1_southeast VALUES ('FL', 'GA'),
       PARTITION q1_northcentral VALUES ('SD', 'WI'),
       PARTITION q1_southcentral VALUES ('OK', 'TX'));

A row is mapped to a partition by checking whether the value of the partitioning column for a row falls within the set of values that describes the partition.

For example, the following rows are inserted as follows:

One of the interesting things to note about list partitioning is that there is no apparent sense of ordering between partitions (unlike range partitioning).

When to Use the Composite Partitioning Method

Composite partitioning partitions data using the range method, and within each partition, subpartitions it using the hash method. Composite partitions are ideal for both historical data and striping, and provide improved manageability of range partitioning and data placement, as well as the parallelism advantages of hash partitioning.

When creating composite partitions, you specify the following:

The following statement creates a composite-partitioned table. In this example, three range partitions are created, each containing eight subpartitions. Because the subpartitions are not named, system generated names are assigned, but the STORE IN clause distributes them across the 4 specified tablespaces (ts1, ...,ts4).

CREATE TABLE scubagear (equipno NUMBER, equipname VARCHAR(32), price NUMBER)
  PARTITION BY RANGE (equipno) SUBPARTITION BY HASH(equipname)
    SUBPARTITIONS 8 STORE IN (ts1, ts2, ts3, ts4)
      (PARTITION p1 VALUES LESS THAN (1000),
       PARTITION p2 VALUES LESS THAN (2000),
       PARTITION p3 VALUES LESS THAN (MAXVALUE));

Each subpartition of a composite-partitioned table is stored its own segment. The partitions of a composite-partitioned table are logical structures only as their data is stored in the segments of their subpartitions. As with partitions, these subpartitions share the same logical attributes. Unlike range partitions in a range-partitioned table, the subpartitions cannot have different physical attributes from the owning partition, although they are not required to reside in the same tablespace.

Creating Partitioned Tables

Creating a partitioned table or index is very similar to creating a non-partitioned table or index (as described in Chapter 15, "Managing Tables"), but you include a partitioning clause. The partitioning clause, and subclauses, that you include depend upon the type of partitioning you want to achieve.

You can partition both regular (heap organized) tables and index-organized tables, including those containing LOB columns. You can create nonpartitioned global indexes, range-partitioned global indexes, and local indexes on partitioned tables.

When you create (or alter) a partitioned table, a row movement clause, either ENABLE ROW MOVEMENT or DISABLE ROW MOVEMENT can be specified. This clause either enables or disables the migration of a row to a new partition if its key is updated. The default is DISABLE ROW MOVEMENT.

The following sections present details and examples of creating partitions for the various types of partitioned tables and indexes:

Creating Range-Partitioned Tables

The PARTITION BY RANGE clause of the CREATE TABLE statement specifies that the table is to be range-partitioned. The PARTITION clauses identify the individual partition ranges, and optional subclauses of a PARTITION clause can specify physical and other attributes specific to a partition's segment. If not overridden at the partition level, partitions inherit the attributes of their underlying table.

In this example, more complexity is added to the example presented earlier for a range-partitioned table. Storage parameters and a LOGGING attribute are specified at the table level. These replace the corresponding defaults inherited from the tablespace level for the table itself, and are inherited by the range partitions. However, since there was little business in the first quarter, the storage attributes for partition sales_q1 are made smaller. The ENABLE ROW MOVEMENT clause is specified to allow the migration of a row to a new partition if an update to a key value is made that would place the row in a different partition.

CREATE TABLE sales 
     ( invoice_no NUMBER,
       sale_year  INT NOT NULL,
       sale_month INT NOT NULL,
       sale_day   INT NOT NULL )
   STORAGE (INITIAL 100K NEXT 50K) LOGGING 
   PARTITION BY RANGE ( sale_year, sale_month, sale_day)
     ( PARTITION sales_q1 VALUES LESS THAN ( 1999, 04, 01 )
        TABLESPACE tsa STORAGE (INITIAL 20K, NEXT 10K),
       PARTITION sales_q2 VALUES LESS THAN ( 1999, 07, 01 )
        TABLESPACE tsb,
       PARTITION sales_q3 VALUES LESS THAN ( 1999, 10, 01 )
        TABLESPACE tsc,
       PARTITION sales q4 VALUES LESS THAN ( 2000, 01, 01 )
        TABLESPACE tsd)
   ENABLE ROW MOVEMENT;

The rules for creating range-partitioned global indexes are similar to those for creating range-partitioned tables. The following is an example of creating a range-partitioned global index on sales_month for the above table. Each index partition is named but is stored in the default tablespace for the index.

CREATE INDEX month_ix ON sales(sales_month)
   GLOBAL PARTITION BY RANGE(sales_month)
      (PARTITION pm1_ix VALUES LESS THAN (2)
       PARTITION pm2_ix VALUES LESS THAN (3)
       PARTITION pm3_ix VALUES LESS THAN (4)
       PARTITION pm4_ix VALUES LESS THAN (5)
       PARTITION pm5_ix VALUES LESS THAN (6)
       PARTITION pm6_ix VALUES LESS THAN (7)
       PARTITION pm7_ix VALUES LESS THAN (8)
       PARTITION pm8_ix VALUES LESS THAN (9)
       PARTITION pm9_ix VALUES LESS THAN (10)
       PARTITION pm10_ix VALUES LESS THAN (11)
       PARTITION pm11_ix VALUES LESS THAN (12)
       PARTITION pm12_ix VALUES LESS THAN (MAXVALUE));

Creating Hash-Partitioned Tables

The PARTITION BY HASH clause of the CREATE TABLE statement identifies that the table is to be hash-partitioned. The PARTITIONS clause can then be used to specify the number of partitions to create, and optionally, the tablespaces to store them in. Alternatively, you can use PARTITION clauses to name the individual partitions and their tablespaces.

The only attribute you can specify for hash partitions is TABLESPACE. All of the hash partitions of a table must share the same segment attributes (except TABLESPACE), which are inherited from the table level.

The following examples illustrate two methods of creating a hash-partitioned table named dept. In the first example the number of partitions is specified, but system generated names are assigned to them and they are stored in the default tablespace of the table.

CREATE TABLE dept (deptno NUMBER, deptname VARCHAR(32))
     PARTITION BY HASH(deptno) PARTITIONS 16;
   

In this second example, names of individual partitions, and tablespaces in which they are to reside, are specified. The initial extent size for each hash partition (segment) is also explicitly stated at the table level, and all partitions inherit this attribute.

CREATE TABLE dept (deptno NUMBER, deptname VARCHAR(32))
     STORAGE (INITIAL 10K)
     PARTITION BY HASH(deptno)
       (PARTITION p1 TABLESPACE ts1, PARTITION p2 TABLESPACE ts2,
        PARTITION p3 TABLESPACE ts1, PARTITION p4 TABLESPACE ts3);

If you create a local index for the above table, Oracle constructs the index so that it is equipartitioned with the underlying table. Oracle also ensures that the index is maintained automatically when maintenance operations are performed on the underlying table. The following is an example of creating a local index on the table dept:

CREATE INDEX locd_dept_ix ON dept(deptno) LOCAL
    

You can optionally name the hash partitions and tablespaces into which the local index partitions are to be stored, but if you do not do so, Oracle uses the name of the corresponding base partition as the index partition name, and store the index partition in the same tablespace as the table partition.

Creating List-Partitioned Tables

The semantics for creating list partitions are very similar to those for creating range partitions. However, to create list partitions, you specify a PARTITION BY LIST clause in the CREATE TABLE statement, and the PARTITION clauses specify lists of literal values, which are the discrete values of the partitioning columns that qualify rows to be included in the partition. Like for range partitions, optional subclauses of a PARTITION clause can specify physical and other attributes specific to a partition's segment. If not overridden at the partition level, partitions inherit the attributes of their underlying table.

In the following example creates table sales_by_region and partitions it using the list method. The first two PARTITION clauses specify physical attributes, which override the table-level defaults. The remaining PARTITION clauses do not specified attributes and those partitions inherit their physical attributes from table-level defaults.

CREATE TABLE sales_by_region (item# INTEGER, qty INTEGER, 
             store_name VARCHAR(30), state_code VARCHAR(2),
             sale_date DATE)
     STORAGE(INITIAL 10K NEXT 20K) TABLESPACE tbs5 
     PARTITION BY LIST (state_code) 
     (
     PARTITION region_east
        VALUES ('MA','NY','CT','NH','ME','MD','VA','PA','NJ')
        STORAGE (INITIAL 20K NEXT 40K PCTINCREASE 50) 
        TABLESPACE tbs8,
     PARTITION region_west
        VALUES ('CA','AZ','NM','OR','WA','UT','NV','CO')
        PCTFREE 25 NOLOGGING,
     PARTITION region_south
        VALUES ('TX','KY','TN','LA','MS','AR','AL','GA'),
     PARTITION region_central 
        VALUES ('OH','ND','SD','MO','IL','MI', null, 'IA')
     );

Creating Composite Partitioned Tables

To create a composite-partitioned table, you start by using the PARTITION BY RANGE clause of a CREATE TABLE statement. Next, you specify a SUBPARTITION BY HASH clause that follows similar syntax and rules as the PARTITION BY HASH statement. The individual PARTITION and SUBPARTITION or SUBPARTITIONS clauses follow.

Attributes specified for a (range) partition apply to all subpartitions of that partition. You can specify different attributes for each (range) partition, and you can specify a STORE IN clause at the partition level if the list of tablespaces across which that partition's subpartitions should be spread is different from those of other partitions. All of this is illustrated in the following example.

CREATE TABLE emp (deptno NUMBER, empname VARCHAR(32), grade NUMBER)   
     PARTITION BY RANGE(deptno) SUBPARTITION BY HASH(empname)
        SUBPARTITIONS 8 STORE IN (ts1, ts3, ts5, ts7)
    (PARTITION p1 VALUES LESS THAN (1000) PCTFREE 40,
     PARTITION p2 VALUES LESS THAN (2000)
        STORE IN (ts2, ts4, ts6, ts8),
     PARTITION p3 VALUES LESS THAN (MAXVALUE)
       (SUBPARTITION p3_s1 TABLESPACE ts4,
        SUBPARTITION p3_s2 TABLESPACE ts5));

The following statement creates a local index on the emp table where the index segments are spread across tablespaces ts7, ts8, and ts9.

CREATE INDEX emp_ix ON emp(deptno)
     LOCAL STORE IN (ts7, ts8, ts9);

This local index is equipartitioned with the base table as follows:

Creating Partitioned Index-Organized Tables

For index-organized tables, you can use the range or hash partitioning method. However, only range partitioned index-organized tables can contain columns with LOBs. The semantics for creating range or hash-partitioned index-organized tables is similar to that for regular tables with these differences:

Specifying an OVERFLOW clause results in the overflow data segments themselves being equi-partitioned with the primary key index segments. Thus, for partitioned index-organized tables with overflow, each partition has an index segment and an overflow data segment.

For index-organized tables, the set of partitioning columns must be a subset of the primary key columns. Since rows of an index-organized table are stored in the primary key index for the table, the partitioning criterion has an effect on the availability. By choosing the partition key to be a subset of the primary key, an insert operation only needs to verify uniqueness of the primary key in a single partition, thereby maintaining partition independence.

Support for secondary indexes on index-organized tables is similar to the support for regular tables, however, certain maintenance operations do not mark global indexes UNUSABLE, as is the case for regular tables.

See Also:

 

Creating Range-Partitioned Index-Organized Tables

You can partition index-organized tables, and their secondary indexes, by the range method. In the following example, a range-partitioned index-organized table sales is created. The INCLUDING clause specifies all columns after week_no are stored in an overflow segment. There is one overflow segment for each partition, all stored in the same tablespace (overflow_here). Optionally, OVERFLOW TABLESPACE could be specified at the individual partition level, in which case some or all of the overflow segments could have separate TABLESPACE attributes.

CREATE TABLE sales(acct_no NUMBER(5), 
                   acct_name CHAR(30), 
                   amount_of_sale NUMBER(6), 
                   week_no INTEGER,
                   sale_details VARCHAR2(1000),
             PRIMARY KEY (acct_no, acct_name, week_no)) 
     ORGANIZATION INDEX 
             INCLUDING week_no
             OVERFLOW TABLESPACE overflow_here
     PARTITION BY RANGE (week_no)
            (PARTITION VALUES LESS THAN (5) 
                   TABLESPACE ts1,
             PARTITION VALUES LESS THAN (9) 
                   TABLESPACE ts2 OVERFLOW TABLESPACE overflow_ts2,
             ...
             PARTITION VALUES LESS THAN (MAXVALUE) 
                   TABLESPACE ts13);

Creating Hash-Partitioned Index-Organized Tables

The other option for partitioning index-organized tables is to use the hash method. In the following example the index-organized table, sales, is partitioned by the hash method.

CREATE TABLE sales(acct_no NUMBER(5), 
                   acct_name CHAR(30), 
                   amount_of_sale NUMBER(6), 
                   week_no INTEGER,
                   sale_details VARCHAR2(1000),
             PRIMARY KEY (acct_no, acct_name, week_no)) 
     ORGANIZATION INDEX 
             INCLUDING week_no
     OVERFLOW
          PARTITION BY HASH (week_no)
             PARTITIONS 16
             STORE IN (ts1, ts2, ts3, ts4)
             OVERFLOW STORE IN (ts3, ts6, ts9);


Note:

Since a well designed hash function is supposed to distribute rows in a well balanced fashion amongst the partitions, updating the primary key column(s) of a row is very likely to move that row to a different partition. Therefore it is recommended that a hash-partitioned index-organized table with a changeable partitioning key be created with the ROW MOVEMENT ENABLE clause explicitly specified. That feature is by default disabled. 


Partitioning Restrictions for Multiple Block Sizes

Use caution when creating partitioned objects in a database with tablespaces of multiple block size. The storage of partitioned objects in such tablespaces is subject to some restrictions. Specifically, all partitions of the following entities must reside in tablespaces of the same block size:

Therefore:

When you create or alter a partitioned table or index, all tablespaces you explicitly specify for the partitions and subpartitions of each entity must be of the same block size. If you do not explicitly specify tablespace storage for an entity, the tablespaces Oracle uses by default must be of the same block size. Therefore you must be aware of the default tablespaces at each level of the partitioned object.

Maintaining Partitioned Tables

This section describes how to perform partition and subpartition maintenance operations for both tables and indexes.

Table 17-1 lists the maintenance operations that can be performed on table partitions (or subpartitions) and, for each type of partitioning, lists the specific clause of the ALTER TABLE statement that is used to perform that maintenance operation.

Table 17-1 ALTER TABLE Maintenance Operations for Table Partitions (Page 1 of 2)
Maintenance Operation  Range   Hash  List  Composite 

Adding Partitions 

ADD PARTITION 

ADD PARTITION 

ADD PARTITION 

ADD PARTITION

MODIFY PARTITION...ADD SUBPARTITION 

Coalescing Partitions 

n/a 

COALESCE PARTITION 

n/a 

MODIFY PARTITION...COALESCE SUBPARTITION 

Dropping Partitions 

DROP PARTITION 

n/a 

DROP PARTITION 

DROP PARTITION 

Exchanging Partitions 

EXCHANGE PARTITION 

EXCHANGE PARTITION 

EXCHANGE PARTITION 

EXCHANGE PARTITION

EXCHANGE SUBPARTITION 

Merging Partitions 

MERGE PARTITIONS 

n/a 

MERGE PARTITIONS 

MERGE PARTITIONS 

Modifying Partitions: Adding Values 

n/a 

n/a 

MODIFY PARTITION...ADD VALUES 

n/a 

Modifying Partitions: Dropping Values 

n/a 

n/a 

MODIFY PARTITION...DROP VALUES 

n/a 

Modifying Default Attributes  

MODIFY DEFAULT ATTRIBUTES  

MODIFY DEFAULT ATTRIBUTES 

MODIFY DEFAULT ATTRIBUTES 

MODIFY DEFAULT ATTRIBUTES

MODIFY DEFAULT ATTRIBUTES FOR PARTITION 

Modifying Real Attributes of Partitions 

MODIFY PARTITION 

MODIFY PARTITION 

MODIFY PARTITION 

MODIFY PARTITION

MODIFY SUBPARTITION 

Moving Partitions 

MOVE PARTITION 

MOVE PARTITION 

MOVE PARTITION 

MOVE SUBPARTITION 

Renaming Partitions 

RENAME PARTITION 

RENAME PARTITION 

RENAME PARTITION 

RENAME PARTITION

RENAME SUBPARTITION 

Splitting Partitions 

SPLIT PARTITION 

n/a 

SPLIT PARTITION 

SPLIT PARTITION 

Truncating Partitions 

TRUNCATE PARTITION 

TRUNCATE PARTITION 

TRUNCATE PARTITION 

TRUNCATE PARTITION

TRUNCATE SUBPARTITION 

Table 17-2 lists the maintenance operations that can be performed on index partitions, and indicates on which type of index (global or local) they can be performed. The ALTER INDEX clause used for the maintenance operation is shown.

Global indexes do not reflect the structure of the underlying table, and if partitioned, they can only be partitioned by range. Range-partitioned indexes share some, but not all, of the partition maintenance operations that can be performed on range-partitioned tables.

Because local indexes reflect the underlying structure of the table, partitioning is maintained automatically when table partitions and subpartitions are affected by maintenance activity. Therefore, partition maintenance on local indexes is less necessary and there are fewer options.

Table 17-2 ALTER INDEX Maintenance Operations for Index Partitions 
Maintenance Operation  Type of Index  Type of Index Partitioning 
Range  Hash/List  Composite 

Dropping Index Partitions 

Global 

DROP PARTITION 

 

 

Local 

n/a 

n/a 

n/a 

Modifying Default Attributes of Index Partitions 

Global 

MODIFY DEFAULT ATTRIBUTES 

 

 

Local 

MODIFY DEFAULT ATTRIBUTES 

MODIFY DEFAULT ATTRIBUTES 

MODIFY DEFAULT ATTRIBUTES

MODIFY DEFAULT ATTRIBUTES FOR PARTITION 

Modifying Real Attributes of Index Partitions 

Global 

MODIFY PARTITION 

 

 

Local 

MODIFY PARTITION 

MODIFY PARTITION 

MODIFY PARTITION

MODIFY SUBPARTITION 

Rebuilding Index Partitions 

Global 

REBUILD PARTITION 

 

 

Local 

REBUILD PARTITION 

REBUILD PARTITION 

REBUILD SUBPARTITION 

Renaming Index Partitions 

Global 

RENAME PARTITION 

 

 

Local 

RENAME PARTITION 

RENAME PARTITION 

RENAME PARTITION

RENAME SUBPARTITION 

Splitting Index Partitions 

Global 

SPLIT PARTITION 

 

 

Local 

n/a 

n/a 

n/a 


Note:

The following sections discuss maintenance operations on partitioned tables. Where the usability of indexes or index partitions affected by the maintenance operation is discussed, consider the following:

  • Only indexes and index partitions that are not empty are candidates for being marked UNUSABLE. If they are empty, the USABLE/UNUSABLE status is left unchained.

  • Only indexes or index partitions with USABLE status are updated by subsequent DML.

 

Updating Global Indexes Automatically

Before discussing the individual maintenance operations for partitioned tables and indexes, it is important to discuss the effects of the UPDATE GLOBAL INDEXES clause that can be specified in the ALTER TABLE statement.

By default, many table maintenance operations on partitioned tables invalidate (mark UNUSABLE) global indexes. You must then rebuild the entire global index or, if partitioned, all of its partitions. Oracle enables you to override this default behavior if you specify UPDATE GLOBAL INDEXES in your ALTER TABLE statement for the maintenance operation. Specifying this clause tells Oracle to update the global index at the time it executes the maintenance operation DDL statement. This provides the following benefits:

But also consider the following performance implications when you specify UPDATE GLOBAL INDEXES:

The following operations support the UPDATE GLOBAL INDEXES clause:

Adding Partitions

This section describes how to add new partitions to a partitioned table and explains why partitions cannot be specifically added to global partitioned or local indexes.

Adding a Partition to a Range-Partitioned Table

Use the ALTER TABLE ... ADD PARTITION statement to add a new partition to the "high" end (the point after the last existing partition). To add a partition at the beginning or in the middle of a table, use the SPLIT PARTITION clause.

For example, consider the table, sales, which contains data for the current month in addition to the previous 12 months. On January 1, 1999, you add a partition for January, which is stored in tablespace tsx.

ALTER TABLE sales 
      ADD PARTITION jan96 VALUES LESS THAN ( '01-FEB-1999' )
      TABLESPACE tsx;

Local and global indexes associated with the range-partitioned table remain usable.

Adding a Partition to a Hash-Partitioned Table

When you add a partition to a hash-partitioned table, Oracle populates the new partition with rows rehashed from an existing partition (selected by Oracle) as determined by the hash function.

The following statements show two ways of adding a hash partition to table scubagear. Choosing the first statement adds a new hash partition whose partition name is system generated, and which is placed in the table's default tablespace. The second statement also adds a new hash partition, but that partition is explicitly named p_named and is created in tablespace gear5.

ALTER TABLE scubagear ADD PARTITION;

ALTER TABLE scubagear
      ADD PARTITION p_named TABLESPACE gear5;

Indexes may be marked UNUSABLE as explained in the following table:

Table Type  Index Behavior 

Regular (Heap) 

  • The local indexes for the new partition, and for the existing partition from which rows were redistributed, are marked UNUSABLE and must be rebuilt.

  • Unless you specify UPDATE GLOBAL INDEXES, all global indexes, or all partitions of partitioned global indexes, are marked UNUSABLE and must be rebuilt.

 

Index-organized 

  • For local indexes, the behavior is the same as for heap tables.

  • All global indexes remain usable.

 

Adding a Partition to a List-Partitioned Table

The following statement illustrates adding a new partition to a list-partitioned table. In this example physical attributes and NOLOGGING are specified for the partition being added.

ALTER TABLE sales_by_region 
   ADD PARTITION region_nonmainland VALUES ('HI', 'PR')
      STORAGE (INITIAL 20K NEXT 20K) TABLESPACE tbs_3
      NOLOGGING;

Any value in the set of literal values that describe the partition(s) being added must not exist in any of the other partitions of the table.

Local and global indexes associated with the list-partitioned table remain usable.

Adding Partitions to a Composite-Partitioned Table

Partitions can be added at both the range partition level and the hash subpartition level.

Adding a Partition

Adding a new range partition to a composite-partitioned table is as described previously in "Adding a Partition to a Range-Partitioned Table". However, you can specify a SUBPARTITIONS clause that allows you to add a specified number of subpartitions, or a SUBPARTITION clause for naming specific subpartitions. If no SUBPARTITIONS or SUBPARTITION clause is specified, the partition inherits table level defaults for subpartitions.

This example adds a range partition q1_2000 to table sales, which will be populated with data for the first quarter of the year 2000. There are eight subpartitions stored in tablespace tbs5.

ALTER TABLE sales ADD PARTITION q1_2000
      VALUES LESS THAN (2000, 04, 01)
      SUBPARTITIONS 8 STORE IN tbs5;
Adding a Subpartition

You use the MODIFY PARTITION ... ADD SUBPARTITION clause of the ALTER TABLE statement to add a hash subpartition to a composite-partitioned table. The newly added subpartition is populated with rows rehashed from other subpartitions of the same partition as determined by the hash function.

In the following example, a new hash subpartition us_loc5, stored in tablespace us1, is added to range partition locations_us in table diving.

ALTER TABLE diving MODIFY PARTITION locations_us
      ADD SUBPARTITION us_locs5 TABLESPACE us1;

Local index subpartitions corresponding to the added and rehashed subpartitions must be rebuilt. Unless you specify UPDATE GLOBAL INDEXES, all global indexes, or all partitions of partitioned global indexes, are marked UNUSABLE and must be rebuilt.

Adding Index Partitions

You cannot explicitly add a partition to a local index. Instead, a new partition is added to a local index only when you add a partition to the underlying table. Specifically, when there is a local index defined on a table and you issue the ALTER TABLE statement to add a partition, a matching partition is also added to the local index. Since Oracle assigns names and default physical storage attributes to the new index partitions, you may want to rename or alter them after the ADD operation is complete.

You cannot add a partition to a global index because the highest partition always has a partition bound of MAXVALUE. If you want to add a new highest partition, use the ALTER INDEX ... SPLIT PARTITION statement.

Coalescing Partitions

Coalescing partitions is a way of reducing the number of partitions in a hash-partitioned table, or the number of subpartitions in a composite-partitioned table. When a hash partition is coalesced, its contents are redistributed into one or more remaining partitions determined by the hash function. The specific partition that is coalesced is selected by Oracle, and is dropped after its contents have been redistributed.

Indexes may be marked UNUSABLE as explained in the following table:

Table Type  Index Behavior 

Regular (Heap) 

  • Any local index partition corresponding to the selected partition is also dropped. Local index partitions corresponding to the one or more absorbing partitions are marked UNUSABLE and must be rebuilt.

  • Unless you specify UPDATE GLOBAL INDEXES, all global indexes, or all partitions of partitioned global indexes, are marked UNUSABLE and must be rebuilt.

 

Index-organized 

  • Some local indexes are marked UNUSABLE as noted above.

  • All global indexes remain usable.

 

Coalescing a Partition in a Hash-Partitioned Table

The ALTER TABLE ... COALESCE PARTITION statement is used to coalesce a partition in a hash-partitioned table. The following statement reduces by one the number of partitions in a table by coalescing a partition.

ALTER TABLE ouu1
     COALESCE PARTITION;

Coalescing a Subpartition in a Composite-Partitioned Table

The following statement distributes the contents of a subpartition of partition us_locations into one or more remaining subpartitions (determined by the hash function) of the same partition. Basically, this operation is the inverse of the MODIFY PARTITION ... ADD SUBPARTITION clause discussed in "Adding a Subpartition".

ALTER TABLE diving MODIFY PARTITION us_locations
     COALESCE SUBPARTITION;

Dropping Partitions

You can drop partitions from range, composite, or list-partitioned tables. For hash-partitioned tables, or hash subpartitions of composite-partitioned tables, you must perform a coalesce operation instead.

Dropping a Table Partition

Use the ALTER TABLE ... DROP PARTITION statement to drop a table partition. If you want to preserve the data in the partition, use the MERGE PARTITION statement instead of the DROP PARTITION statement.

If there are local indexes defined for the table, this statement also drops the matching partition or subpartitions from the local index. All global indexes, or all partitions of partitioned global indexes, are marked UNUSABLE unless either of the following are true:

The following sections contain some scenarios for dropping table partitions.

Dropping a Partition from a Table that Contains Data and Global Indexes

If the partition contains data and one or more global indexes are defined on the table, use one of the following methods to drop the table partition.

Method 1:

Method 2:

Method 3:

Dropping a Partition Containing Data and Referential Integrity Constraints

If a partition contains data and the table has referential integrity constraints, choose either of the following methods to drop the table partition. This table has a local index only, so it is not necessary to rebuild any indexes.

Method 1:

Method 2:

Dropping Index Partitions

You cannot explicitly drop a partition of 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. But, if a global index partition contains data, dropping the partition causes the next highest partition to be marked UNUSABLE. For example, you would like to drop the index partition P1, and P2 is the next highest partition. You must issue the following statements:

ALTER INDEX npr DROP PARTITION P1;
ALTER INDEX npr REBUILD PARTITION P2;


Note:

You cannot drop the highest partition in a global index. 


Exchanging Partitions

You can convert a partition (or subpartition) into a nonpartitioned table, and a nonpartitioned table into a partition (or subpartition) of a partitioned table by exchanging their data segments. You can also convert a hash-partitioned table into a partition of a composite-partitioned table, or convert the partition of the composite-partitioned table into a hash-partitioned table.

Exchanging table partitions is most useful when you have an application using nonpartitioned tables that you want to convert to partitions of a partitioned table. For example, you could already have partition views that you want to migrate into partitioned tables.

Exchanging partitions also facilitates high-speed data loading when used with transportable tablespaces.

When you exchange partitions, logging attributes are preserved. You can optionally specify if local indexes are also to be exchanged, and if rows are to be validated for proper mapping. Unless you specify UPDATE GLOBAL INDEXES (cannot be specified for index-organized tables), Oracle marks UNUSABLE the global indexes, or all global index partitions, on the table whose partition is being exchanged. Any global indexes, or global index partitions, on the table being exchanged are marked UNUSABLE.

See Also:

 

Exchanging a Range, Hash, or List Partition

To exchange a partition of a range, hash, or list-partitioned table with a nonpartitioned table, or the reverse, use the ALTER TABLE ... EXCHANGE PARTITION statement. An example of converting a partition into a nonpartitioned table follows. In this example, table stocks can be range, hash, or list partitioned.

ALTER TABLE stocks
    EXCHANGE PARTITION p3 WITH stock_table_3;

Exchanging a Hash-Partitioned Table with a Composite Partition

In this example, you are exchanging a whole hash-partitioned table, with all of its partitions, with a composite-partitioned table's range partition and all of its hash subpartitions. This is illustrated in the following example.

First, create a hash-partitioned table:

CREATE TABLE t1 (i NUMBER, j NUMBER)
     PARTITION BY HASH(i)
       (PARTITION p1, PARTITION p2);

Populate the table, then create a composite-partitioned table as shown:

CREATE TABLE t2 (i NUMBER, j NUMBER)
     PARTITION BY RANGE(j)
     SUBPARTITION BY HASH(i)
        (PARTITION p1 VALUES LESS THAN (10)
            SUBPARTITION t2_pls1
            SUBPARTITION t2_pls2,
         PARTITION p2 VALUES LESS THAN (20)
            SUBPARTITION t2_p2s1
            SUBPARTITION t2_p2s2));

It is important that the partitioning key in table t1 is the same as the subpartitioning key in table t2.

To migrate the data in t1 to t2, and validate the rows, use the following statement:

ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t2
     WITH VALIDATION;

Exchanging a Subpartition of a Composite-Partitioned Table

Use the ALTER TABLE ... EXCHANGE SUBPARTITION statement to convert a hash subpartition of a composite-partitioned table into a nonpartitioned table, or the reverse. The following example converts the subpartition q3_1999_s1 of table sales into the nonpartitioned table q3_1999. Local index partitions are exchanged with corresponding indexes on q3_1999.

ALTER TABLE sales EXCHANGE SUBPARTITIONS q3_1999_s1
      WITH TABLE q3_1999 INCLUDING INDEXES;

Merging Partitions

Use the ALTER TABLE ... MERGE PARTITIONS statement to merge the contents of two partitions into one partition. The two original partitions are dropped, as are any corresponding local indexes.

You cannot use this statement for a hash-partitioned table or for hash subpartitions of a composite-partitioned table.

Unless the involved partitions or subpartitions are empty, indexes may be marked UNUSABLE as explained in the following table:

Table Type  Index Behavior 

Regular (Heap) 

  • Oracle marks UNUSABLE all resulting corresponding local index partitions or subpartitions.

  • Unless you specify UPDATE GLOBAL INDEXES, all global indexes, or all partitions of partitioned global indexes, are marked UNUSABLE and must be rebuilt.

 

Index-organized 

  • Oracle marks UNUSABLE all resulting corresponding local index partitions or subpartitions.

  • All global indexes remain usable.

 

Merging Range Partitions

You are allowed to merge the contents of two adjacent range partitions into one partition. Non adjacent range partitions cannot be merged. The resulting partition inherits the higher upper bound of the two merged partitions.

One reason for merging range partitions is to keep historical data online in larger partitions. For example, you can have daily partitions, with the oldest partition rolled up into weekly partitions, which can then be rolled up into monthly partitions, and so on.

The following scripts create an example of merging range partitions.

First, create a partitioned table and create local indexes.

-- Create a Table with four partitions each on its own tablespace
-- Partitioned by range on the data column.
--
CREATE TABLE four_seasons
( 
        one DATE,
        two VARCHAR2(60),
        three NUMBER
)
PARTITION  BY RANGE ( one ) 
(
PARTITION quarter_one 
   VALUES LESS THAN ( TO_DATE('01-apr-1998','dd-mon-yyyy'))
   TABLESPACE quarter_one,
PARTITION quarter_two 
   VALUES LESS THAN ( TO_DATE('01-jul-1998','dd-mon-yyyy'))
   TABLESPACE quarter_two,
PARTITION quarter_three
   VALUES LESS THAN ( TO_DATE('01-oct-1998','dd-mon-yyyy'))
   TABLESPACE quarter_three,
PARTITION quarter_four
   VALUES LESS THAN ( TO_DATE('01-jan-1999','dd-mon-yyyy'))
   TABLESPACE quarter_four
)
/
-- 
-- Create local PREFIXED index on Four_Seasons
-- Prefixed because the leftmost columns of the index match the
-- Partition key 
--
CREATE INDEX i_four_seasons_l ON four_seasons ( one,two ) 
LOCAL ( 
PARTITION i_quarter_one TABLESPACE i_quarter_one,
PARTITION i_quarter_two TABLESPACE i_quarter_two,
PARTITION i_quarter_three TABLESPACE i_quarter_three,
PARTITION i_quarter_four TABLESPACE i_quarter_four
)
/ 

Next, merge partitions.

--
-- Merge the first two partitions 
--
ALTER TABLE four_seasons 
MERGE PARTITIONS quarter_one, quarter_two INTO PARTITION quarter_two
/

Then, rebuild the local index for the affected partition.

-- Rebuild index for quarter_two, which has been marked unusable 
-- because it has not had all of the data from Q1 added to it.
-- Rebuilding the index will correct this.
--
ALTER TABLE four_seasons MODIFY PARTITION 
quarter_two REBUILD UNUSABLE LOCAL INDEXES
/   

Merging List Partitions

When you merge list partitions, the partitions being merged can be any two partitions. They do not need to be adjacent, as for range partitions, since list partitioning does not assume any order for partitions. The resulting partition consists of all of the data from the original two partitions.

The statement below merges two partitions of a table partitioned using the list method into a partition that inherits all of its attributes from the table-level default attributes, except for PCTFREE and MAXEXTENTS, which are specified in the statement.

ALTER TABLE sales_by_region 
   MERGE PARTITIONS sales_northwest, sales_southwest 
   INTO PARTITION sales_west 
      PCTFREE 50 STORAGE(MAXEXTENTS 20);

The value lists for the two original partitions were specified as:

PARTITION sales_northwest VALUES ('WA','OR','WY','MT')
PARTITION sales_southwest VALUES ('AZ','NM','CO')

The resulting sales_west partition's value list comprises the set that represents the union of these two partition value lists, or specifically:

('WA','OR','WY','MT','AZ','NM','CO')

Merging Range Composite Partitions

When you merge range composite partitions, the subpartitions are rehashed into either the number of subpartitions specified in a SUBPARTITIONS or SUBPARTITION clause, or, if no such clause is included, table-level defaults are used.

Note that the inheritance of properties is different when a range composite partition is split (discussed in "Splitting a Range Composite Partition"), verses when two range composite partitions are merged. When a partition is split, the new partitions can inherit properties from the original partition since there is only one parent. However, when partitions are merged, properties must be inherited from table level defaults because there are two parents and the new partition cannot inherit from either at the expense of the other.

The following example merges two range composite partitions:

ALTER TABLE all_seasons
     MERGE PARTITIONS quarter_1, quarter_2 INTO PARTITION quarter_2
     SUBPARTITIONS 8;

Modifying Default Attributes

You can modify the default attributes of a table, or for a partition of a composite-partitioned table. When you modify default attributes, the new attributes affect only future partitions, or subpartitions, that are created. The default values can still be specifically overridden when creating a new partition or subpartition.

Modifying Default Attributes of a Table

You modify the default attributes that will be inherited for range, list, or hash partitions using the MODIFY DEFAULT ATTRIBUTES clause of ALTER TABLE. The following example changes the default value of PCTFREE in table emp for any new partitions that are created.

ALTER TABLE emp
      MODIFY DEFAULT ATTRIBUTES PCTFREE 25;

For hash-partitioned tables, only the TABLESPACE attribute can be modified.

Modifying Default Attributes of a Partition

To modify the default attributes inherited when creating subpartitions, use the ALTER TABLE ... MODIFY DEFAULT ATTRIBUTES FOR PARTITION. The following statement modifies the TABLESPACE in which future subpartitions of partition p1 in composite-partitioned table emp will reside.

ALTER TABLE emp
     MODIFY DEFAULT ATTRIBUTES FOR PARTITION p1 TABLESPACE ts1;

Since all subpartitions must share the same attributes, except TABLESPACE, it is the only attribute that can be changed.

Modifying Default Attributes of Index Partitions

In similar fashion to table partitions, you can alter the default attributes that will be inherited by partitions of a range-partitioned global index, or local index partitions for range, hash, or composite-partitioned tables. For this you use the ALTER INDEX ... MODIFY DEFAULT ATTRIBUTES statement. Use the ALTER INDEX ... MODIFY DEFAULT ATTRIBUTES FOR PARTITION statement if you are altering default attributes to be inherited by subpartitions of a composite-partitioned table.

Modifying Real Attributes of Partitions

It is possible to modify attributes of an existing partition of a table or index.

You cannot change the TABLESPACE attribute. Use ALTER TABLESPACE ... MOVE PARTITION/SUBPARTITION to move a partition or subpartition to a new tablespace.

Modifying Real Attributes for a Range or List Partition

Use the ALTER TABLE ... MODIFY PARTITION statement to modify existing attributes of a range partition. You can modify segment attributes (except TABLESPACE), or you can allocate and deallocate extents, mark local index partitions UNUSABLE, or rebuild local indexes that have been marked UNUSABLE.

If this is a range partition of a composite-partitioned table, note the following:

The following are some examples of modifying the real attributes of a partition.

This example modifies the MAXEXTENTS storage attribute for the range partition sales_q1 of table sales:

ALTER TABLE sales MODIFY PARTITION sales_Q1
     STORAGE (MAXEXTENTS 10); 

All of the local index subpartitions of partition ts1 in composite-partitioned table scubagear are marked UNUSABLE in the following example:

ALTER TABLE scubagear MPDIFY PARTITION ts1 UNUSABLE LOCAL INDEXES;

Modifying Real Attributes for a Hash Partition

You also use the ALTER TABLE ... MODIFY PARTITION statement to modify attributes of a hash partition. However, since the physical attributes of individual hash partitions must all be the same (except for TABLESPACE), you are restricted to:

The following example rebuilds any unusable local index partitions associated with hash partition P1 of table dept:

ALTER TABLE dept MODIFY PARTITION p1
     REBUILD UNUSABLE LOCAL INDEXES;

Modifying Real Attributes of a Subpartition

With the MODIFY SUBPARTITION clause of ALTER TABLE you can perform the same actions as listed previously for hash partitions, but at the specific composite-partitioned table subpartition level. For example:

ALTER TABLE emp MODIFY SUBPARTITION p3_s1
     REBUILD UNUSABLE LOCAL INDEXES

Modifying Real Attributes of Index Partitions

The MODIFY PARTITION clause of ALTER INDEX allows you to modify the real attributes of an index partition or its subpartitions. The rules are very similar to those for table partitions, but unlike the MODIFY PARTITION clause for ALTER TABLE, there is no subclause to rebuild an unusable index partition, but there is a subclause to coalesce an index partition or its subpartitions. In this context, coalesce means to merge index blocks where possible to free them for reuse.

You can also allocate or deallocate storage for a subpartition of a local index, or mark it UNUSABLE, using the MODIFY SUBPARTITION clause.

Modifying List Partitions: Adding or Dropping Values

List partitioning allows you the option of adding or dropping literal values from the defining value list.

Modifying Partitions: Adding Values

Use the MODIFY PARTITION ... ADD VALUES clause of the ALTER TABLE statement to extend the value list of an existing partition. Literal values being added must not have been included in any other partition's value list. The partition value list for any corresponding local index partition is correspondingly extended, and any global index, or global or local index partitions, remain usable.

The following statement adds a new set of state codes ('OK', 'KS') to an existing partition list.

ALTER TABLE sales_by_region
   MODIFY PARTITION region_east
      ADD VALUES ('OK', 'KS');

Modifying Partitions: Dropping Values

Use the MODIFY PARTITION ... DROP VALUES clause of the ALTER TABLE statement to remove literal values from the value list of an existing partition. The statement is always executed with validation, meaning that it checks to see if any rows exist in the partition that correspond to the set of values being dropped. If any such rows are found then Oracle returns an error message and the operation fails. When necessary, use a DELETE statement to delete corresponding rows from the table before attempting to drop values.


Note:

You cannot drop all literal values from the value list describing the partition. You must use the ALTER TABLE ... DROP PARTITION statement instead. 


The partition value list for any corresponding local index partition reflects the new value list, and any global index, or global or local index partitions, remain usable.

The statement below drops a set of state codes ('OK' and 'KS') from an existing partition value list.

ALTER TABLE sales_by_region
   MODIFY PARTITION region_south
      DROP VALUES ('OK', 'KS');


Note:

Since a query is executed to check for the existence of rows in the partition that correspond to the literal values being dropped, it is advisable to create a local prefixed index on the table. This speeds up the execution of the query and the overall operation. 


Moving Partitions

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 using an ALTER TABLE/INDEX ... MODIFY PARTITION statement. However, there are some physical attributes, such as TABLESPACE, that you cannot modify using MODIFY PARTITION. In these cases, use the MOVE PARTITION clause.

Unless the partition being moved does not contain any data, indexes may be marked UNUSABLE according to the following table:

Table Type  Index Behavior 

Regular (Heap) 

  • The matching partition in each local index is marked UNUSABLE. You must rebuild these index partitions after issuing MOVE PARTITION.

  • Unless you specify UPDATE GLOBAL INDEXES, any global indexes, or all partitions of partitioned global indexes, are marked UNUSABLE.

 

Index-organized 

Any local or global indexes defined for the partition being moved remain usable because they are primary-key based logical rowids. However, the guess information for these rowids becomes incorrect. 

Moving Table Partitions

Use the MOVE PARTITION clause to move a partition. For example, to move the most active partition to a tablespace that resides on its own disk (in order to balance I/O) and to not log the action, 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 do not specify a new tablespace.

Moving Subpartitions

The following statement shows how to move data in a subpartition of a table. In this example, a PARALLEL clause has also been specified.

ALTER TABLE scuba_gear MOVE SUBPARTITION bcd_types 
     TABLESPACE tbs23 PARALLEL (DEGREE 2);

Moving Index Partitions

The ALTER TABLE ... MOVE PARTITION statement for regular tables, marks 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.

Rebuilding Index Partitions

Some reasons for rebuilding index partitions include:

The following sections discuss your options for rebuilding index partitions and subpartitions.

Rebuilding Global Index Partitions

You can rebuild global index partitions in two ways:

  1. Rebuild each partition by issuing the ALTER INDEX ... REBUILD PARTITION statement (you can run the rebuilds concurrently).

  2. Drop the entire global index and re-create it.

    Note:

    This second method is more efficient because the table is scanned only once. 

For most maintenance operations on partitioned tables with global indexes, you can optionally avoid the need to rebuild the global index by specifying UPDATE GLOBAL INDEXES on your DDL statement.

Rebuilding Local Index Partitions

Rebuild local indexes using either ALTER INDEX or ALTER TABLE as follows:

Using Alter Index to Rebuild a Partition

The ALTER INDEX ... REBUILD PARTITION statement rebuilds one partition of an index. It cannot be used on a composite-partitioned table. When you re-create the index, you can also choose to move the partition to a new tablespace or change attributes.

For composite-partitioned tables, use ALTER INDEX ... REBUILD SUBPARTITION to rebuild a subpartition of an index. You can move the subpartition to another tablespace or specify a parallel clause. The following statement rebuilds a subpartition of a local index on a table and moves the index subpartition is another tablespace.

ALTER INDEX scuba
   REBUILD SUBPARTITION bcd_types
   TABLESPACE tbs23 PARALLEL (DEGREE 2);
Using Alter Table to Rebuild an Index Partition

The REBUILD UNUSABLE LOCAL INDEXES clause of ALTER TABLE ... MODIFY PARTITION does not allow you to specify any new attributes for the rebuilt index partition. The following example finds and rebuilds any unusable local index partitions for table scubagear, partition p1.

ALTER TABLE scubagear
   MODIFY PARTITION p1 REBUILD UNUSABLE LOCAL INDEXES;

There is a corresponding ALTER TABLE ... MODIFY SUBPARTITION clause for rebuilding unusable local index subpartitions.

Renaming Partitions

It is possible to rename partitions and subpartitions of both tables and indexes. One reason for renaming a partition might be to assign a meaningful name, as opposed to a default system name that was assigned to the partition in another maintenance operation.

Renaming a Table Partition

Rename a range, hash, or list partition, using the ALTER TABLE ... RENAME PARTITION statement. For example:

ALTER TABLE scubagear RENAME PARTITION sys_p636 TO tanks;

Renaming a Table Subpartition

Likewise, you can assign new names to subpartitions of a table. In this case you would use the ALTER TABLE ... RENAME SUBPARTITION syntax.

Renaming Index Partitions

Index partitions and subpartitions can be renamed in similar fashion, but the ALTER INDEX syntax is used.

Renaming an Index Partition

Use the ALTER INDEX ... RENAME PARTITION statement to rename an index partition.

Renaming an Index Subpartition

This next statement simply shows how to rename a subpartition that has a system generated name that was a consequence of adding a partition to an underlying table:

ALTER INDEX scuba RENAME SUBPARTITION sys_subp3254 TO bcd_types;

Splitting Partitions

The SPLIT PARTITION clause of the ALTER TABLE or ALTER INDEX statement is used to redistribute the contents of a partition into two new partitions. Consider doing this when a partition becomes too large and causes backup, recovery, or maintenance operations to take a long time to complete. You can also use the SPLIT PARTITION clause to redistribute the I/O load.

This clause cannot be used for hash partitions or subpartitions.

Unless the partition you are splitting does not contain any data, indexes may be marked UNUSABLE as explained in the following table:

Table Type  Index Behavior 

Regular (Heap) 

  • Oracle marks UNUSABLE the new partitions (there are two) in each local index.

  • Unless you specify UPDATE GLOBAL INDEXES, any global indexes, or all partitions of partitioned global indexes, are marked UNUSABLE and must be rebuilt.

 

Index-organized 

  • Oracle marks UNUSABLE the new partitions (there are two) in each local index.

  • All global indexes remain usable.

 

Splitting a Partition of a Range-Partitioned Table

You split a range partition using the ALTER TABLE ... SPLIT PARTITION statement. You can optionally specify new attributes for the two partitions resulting from the split. If there are local indexes defined on the table, this statement also splits the matching partition in each local index.

In the following example 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, issue 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 fee_katy1;
ALTER INDEX JAF1 REBUILD PARTITION fee_katy2;
ALTER INDEX VET REBUILD PARTITION vet_parta;
ALTER INDEX VET REBUILD PARTITION vet_partb;


Note:

If you do not specify new partition names, Oracle assigns names of the form SYS_Pn. You can examine the data dictionary to locate the names assigned to the new local index partitions. You may want to rename them. Any attributes you do not specify are inherited from the original partition.  


Splitting a Partition of a List-Partitioned Table

You split a list partition using the ALTER TABLE ... SPLIT PARTITION statement. The SPLIT PARTITION clause allows you to specify a value list of literal values for which rows with corresponding partitioning key values are inserted into the first new partition. The remaining rows of the original partition are inserted into the second partition.

You can optionally specify new attributes for the two partitions resulting from the split.

The following statement splits the partition region_east into 2 partitions:

ALTER TABLE sales_by_region 
   SPLIT PARTITION region_east VALUES ('CT', 'VA', 'MD') 
   INTO 
    ( PARTITION region_east_1 
         PCTFREE 25 TABLESPACE tbs2,
      PARTITION region_east_2
        STORAGE (NEXT 2M PCTINCREASE 25)) 
   PARALLEL 5;

The literal-value list for the original region_east partition was specified as:

PARTITION region_east VALUES ('CT','VA','MD','NY','NH','ME','VA','PA','NJ')

The two new partition's are:

The individual partitions have new physical attributes specified at the partition level. The operation is executed with parallelism of degree 5.

Splitting a Range Composite Partition

This is the opposite of merging range composite partitions. When you split range composite partitions, the new subpartitions are rehashed into either the number of subpartitions specified in a SUBPARTITIONS or SUBPARTITION clause. Or, if no such clause is included, the new partitions inherit the number of subpartitions (and tablespaces) from the partition being split.

Note that the inheritance of properties is different when a range composite partition is split, verses when two range composite partitions are merged. When a partition is split, the new partitions can inherit properties from the original partition since there is only one parent. However, when partitions are merged, properties must be inherited from table level defaults because there are two parents and the new partition cannot inherit from either at the expense of the other.

The following example splits a range composite partition:

ALTER TABLE all_seasons SPLIT PARTITION quarter_1 
     AT (TO_DATE('16-dec-1997','dd-mon-yyyy'))
     INTO (PARTITION q1_1997_1 SUBPARTITIONS 4 STORE IN (ts1,ts3),
           PARTITION q1_1997_2);

Splitting Index 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. However, you can split a global index partition as is done in the following example:

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;

The index being split can contain index data, and the resulting partitions do not require rebuilding, unless the original partition was previously marked UNUSABLE.

Truncating Partitions

Use the ALTER TABLE ... TRUNCATE PARTITION statement to remove all rows from a table partition. Truncating a partition is similar to dropping a partition, except that the partition is emptied of its data, but not physically dropped.

You cannot truncate an index partition. However, if there are local indexes defined for the table, the ALTER TABLE TRUNCATE PARTITION statement truncates the matching partition in each local index. Unless you specify UPDATE GLOBAL INDEXES (cannot be specified for index-organized tables), any global indexes, or all partitions of partitioned global indexes, are marked UNUSABLE and must be rebuilt.

Truncating a Table Partition

Use the ALTER TABLE ... TRUNCATE PARTITION statement to remove all rows from a table partition, with or without reclaiming space.

Truncating Table Partitions Containing Data and Global Indexes

If the partition contains data and global indexes, use one of the following methods to truncate the table partition.

Method 1:

Method 2:

Method 3:

Truncating a Partition Containing Data and Referential Integrity Constraints

If a partition contains data and has referential integrity constraints, choose either of the following methods to truncate the table partition.

Method 1:

Method 2:

Truncating a Subpartition

You use the ALTER TABLE ... TRUNCATE SUBPARTITION statement to remove all rows from a subpartition of a composite-partitioned table. Corresponding local index subpartitions are also truncated.

The following statement shows how to truncate data in a subpartition of a table. In this example, the space occupied by the deleted rows is made available for use by other schema objects in the tablespace.

ALTER TABLE diving
   TRUNCATE SUBPARTITION us_locations
      DROP STORAGE;

Partitioned Tables and Indexes Examples

This section presents some examples for working with partitioned tables and indexes.

Moving the Time Window in a Historical Table

A 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, and orders. Historical tables can also be rollup tables, which contain summary information derived from the base information using operations such as GROUP BY, AVERAGE, or COUNT.

The time interval in a historical table is often a rolling window. DBAs periodically delete sets of rows that describe the oldest transactions, and in turn allocate space for sets of rows that describe the most recent transactions. 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. These monthly partitions are named order_yymm, as are the tablespaces in which they reside.

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:

  1. Back up the data for the oldest time interval.

    ALTER TABLESPACE order_9310 BEGIN BACKUP;
    ...
    ALTER TABLESPACE order_9310 END BACKUP;
    
    
    
  2. Drop the partition for the oldest time interval.

    ALTER TABLE order DROP PARTITION order_9310;
    
    
    
  3. Add the partition to the most recent time interval.

    ALTER TABLE order ADD PARTITION order_9411;
    
    
    
  4. Recreate the global index partitions.

    ALTER INDEX order_ix_cust REBUILD PARTITION order_ix_cust_AH;
    ALTER INDEX order_ix_cust REBUILD PARTITION order_ix_cust_IP;
    ALTER INDEX order_ix_cust REBUILD PARTITION order_ix_cust_QZ;
    
    

Ordinarily, Oracle acquires sufficient locks to ensure that no operation (DML, DDL, or 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. Some methods for doing this are:

Converting a Partition View into a Partitioned Table

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 AS
      SELECT * FROM accounts_jan98
      UNION ALL
      SELECT * FROM accounts_feb98
      UNION ALL
      ...
      SELECT * FROM accounts_dec98;

To incrementally migrate the partition view to a partitioned table, follow these steps:

  1. Initially, only the two most recent partitions, accounts_nov98 and accounts_dec98, will be migrated from the view to the table by creating the partitioned table. Each partition gets a segment of two blocks (as a placeholder).

    CREATE TABLE accounts_new (...)
        TABLESPACE ts_temp STORAGE (INITIAL 2)
        PARTITION BY RANGE (opening_date)
             (PARTITION jan98 VALUES LESS THAN ('01-FEB-1998'),
              ...
             PARTITION dec98 VALUES LESS THAN ('01-JAN-1999'));
    
    
  2. Use the EXCHANGE PARTITION statement to migrate the tables to the corresponding partitions.

    ALTER TABLE accounts_new
        EXCHANGE PARTITION nov98 WITH TABLE 
            accounts_nov98 WITH VALIDATION;
    
    ALTER TABLE accounts_new
        EXCHANGE PARTITION dec98 WITH TABLE
            accounts_dec98 WITH VALIDATION;
    
    

    So now the placeholder data segments associated with the nov98 and dec98 partitions have been exchanged with the data segments associated with the accounts_nov98 and accounts_dec98 tables.

  3. Redefine the accounts view.

    CREATE OR REPLACE VIEW accounts AS
        SELECT * FROM accounts_jan98
        UNION ALL
        SELECT * FROM accounts_feb_98
        UNION ALL
        ...
        UNION ALL
        SELECT * FROM accounts_new PARTITION (nov98)
        UNION ALL
        SELECT * FROM accounts_new PARTITION (dec98);
    
    
  4. Drop the accounts_nov98 and accounts_dec98 tables, which own the placeholder segments that were originally attached to the nov98 and dec98 partitions.

  5. After all the tables in the UNION ALL view are converted into partitions, drop the view and rename the partitioned to the name of the view being dropped.

    DROP VIEW accounts;
    RENAME accounts_new TO accounts;
    

Viewing Information About Partitioned Tables and Indexes

The following views display information specific to partitioned tables and indexes:

View  Description 

DBA_PART_TABLES

ALL_PART_TABLES

USER_PART_TABLES 

DBA view displays partitioning information for all partitioned tables in the database. ALL view displays partitioning information for all partitioned tables accessible to the user. USER view is restricted to partitioning information for partitioned tables owned by the user.  

DBA_TAB_PARTITIONS

ALL_TAB_PARTITIONS

USER_TAB_PARTITIONS 

Display partition-level partitioning information, partition storage parameters, and partition statistics determined by ANALYZE statements for partitions. 

DBA_TAB_SUBPARTITIONS

ALL_TAB_SUBPARTITIONS

USER_TAB_SUBPARTITIONS 

Display subpartition-level partitioning information, subpartition storage parameters, and subpartition statistics determined by ANALYZE operations for partitions.

 

DBA_PART_KEY_COLUMNS

ALL_PART_KEY_COLUMNS

USER_PART_KEY_COLUMNS 

Display the partitioning key columns for partitioned tables.  

DBA_SUBPART_KEY_COLUMNS

ALL_SUBPART_KEY_COLUMNS

USER_SUBPART_KEY_COLUMNS 

Display the subpartitioning key columns for composite-partitioned tables (and local indexes on composite-partitioned tables).  

DBA_PART_COL_STATISTICS

ALL_PART_COL_STATISTICS

USER_PART_COL_STATISTICS 

Display column statistics and histogram information for the partitions of tables.  

DBA_SUBPART_COL_STATISTICS

ALL_SUBPART_COL_STATISTICS

USER_SUBPART_COL_STATISTICS 

Display column statistics and histogram information for subpartitions of tables.  

DBA_PART_HISTOGRAMS

ALL_PART_HISTOGRAMS

USER_PART_HISTOGRAMS 

Display the histogram data (end-points for each histogram) for histograms on table partitions.  

DBA_SUBPART_HISTOGRAMS

ALL_SUBPART_HISTOGRAMS

USER_SUBPART_HISTOGRAMS 

Display the histogram data (end-points for each histogram) for histograms on table subpartitions.  

DBA_PART_INDEXES

ALL_PART_INDEXES

USER_PART_INDEXES 

Display partitioning information for partitioned indexes.  

DBA_IND_PARTITIONS

ALL_IND_PARTITIONS

USER_IND_PARTITIONS 

Display the following for index partitions: partition-level partitioning information, storage parameters for the partition, statistics collected by ANALYZE statements.  

DBA_IND_SUBPARTITIONS

ALL_IND_SUBPARTITIONS

USER_IND_SUBPARTITIONS 

Display the following for index subpartitions: partition-level partitioning information, storage parameters for the partition, statistics collected by ANALYZE statements. 

See Also:

 


Go to previous page Go to next page
Oracle
Copyright © 1996-2001, Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback