Oracle9i Database Administrator's Guide
Release 1 (9.0.1)

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

Master Index


Go to previous page Go to next page

Managing Tables

This chapter describes the various aspects of managing tables, and includes the following topics:

Guidelines for Managing Tables

This section describes guidelines to follow when managing tables. Following these guidelines can make the management of your tables easier, and improve performance both when creating the table and later querying or updating it.

The following topics are discussed:

Design Tables Before Creating Them

Usually, the application developer is responsible for designing the elements of an application, including the tables. Database administrators are responsible for setting storage parameters and defining clusters for tables, based on information from the application developer about how the application works and the types of data expected.

Working with your application developer, carefully plan each table so that the following occurs:

Specify How Data Block Space Is to Be Used

By specifying the PCTFREE and PCTUSED parameters during the creation of each table, you can affect the efficiency of space utilization and amount of space reserved for updates to the current data in the data blocks of a table's data segment. The PCTFREE and PCTUSED parameters are discussed in "Managing Space in Data Blocks".

Specify the Location of Each Table

If you have the proper privileges and tablespace quota, you can create a new table in any tablespace that is currently online. It is advisable to specify the TABLESPACE clause in a CREATE TABLE statement to identify the tablespace that is to store the new table. If you do not specify a tablespace in a CREATE TABLE statement, the table is created in your default tablespace.

When specifying the tablespace to contain a new table, make sure that you understand implications of your selection. By properly specifying a tablespace during the creation of each table, you can:

The following situations illustrate how specifying incorrect storage locations for schema objects can affect a database:

Chapter 24, "Managing Users and Resources" contains information about assigning default tablespaces and tablespace quotas to users.

Consider Parallelizing Table Creation

You can utilize parallel execution when creating tables using a subquery (AS SELECT) in the CREATE TABLE statement. Because multiple processes work together to create the table, performance of the table creation operation is improved.

Parallelizing table creation is discussed in the section "Parallelizing Table Creation".

Consider Using NOLOGGING When Creating Tables

To create a table most efficiently use the NOLOGGING clause in the CREATE TABLE ... AS SELECT statement. The NOLOGGING clause causes minimal redo information to be generated during the table creation. This has the following benefits:

The NOLOGGING clause also specifies that subsequent direct loads using SQL*Loader and direct load INSERT operations are not logged. Subsequent DML statements (UPDATE, DELETE, and conventional path insert) are unaffected by the NOLOGGING attribute of the table and generate redo.

If you cannot afford to lose the table after you have created it (for example, you will no longer have access to the data used to create the table) you should take a backup immediately after the table is created. In some situations, such as for tables that are created for temporary use, this precaution may not be necessary.

In general, the relative performance improvement of specifying NOLOGGING is greater for larger tables than for smaller tables. For small tables, NOLOGGING has little effect on the time it takes to create a table. However, for larger tables the performance improvement can be significant, especially when you are also parallelizing the table creation.

Estimate Table Size and Set Storage Parameters

Estimating the sizes of tables before creating them is useful for the following reasons:

Whether or not you estimate table size before creation, you can explicitly set storage parameters when creating each table. (Clustered tables, discussed in Chapter 18, "Managing Clusters", automatically use the storage parameters of the cluster.) Any storage parameter that you do not explicitly set when creating or subsequently altering a table automatically uses the corresponding default storage parameter set for the tablespace in which the table resides. Storage parameters are discussed in "Setting Storage Parameters".

If you explicitly set the storage parameters for the extents of a table's data segment, try to store the table's data in a small number of large extents rather than a large number of small extents.

Plan for Large Tables

There are no limits on the physical size of tables and extents. You can specify the keyword UNLIMITED for MAXEXTENTS, thereby simplifying your planning for large objects, reducing wasted space and fragmentation, and improving space reuse. However, when the number of extents in a table grows very large, you can see an impact on performance when performing any operation requiring that table.


You cannot alter data dictionary tables to have MAXEXTENTS greater than the allowed block maximum. 

If you have large tables in your database, consider the following recommendations:

Table Restrictions

Here are some restrictions to be aware of before you create tables:

Creating Tables

To create a new table in your schema, you must have the CREATE TABLE system privilege. To create a table in another user's schema, you must have the CREATE ANY TABLE system privilege. Additionally, the owner of the table must have a quota for the tablespace that contains the table, or the UNLIMITED TABLESPACE system privilege.

Create tables using the SQL statement CREATE TABLE.

See Also:

Oracle9i SQL Reference for exact syntax of the CREATE TABLE and other SQL statements discussed in this chapter 

Creating a Table

When user scott issues the following statement, he creates a table named emp in his schema and stores it in the users tablespace:

CREATE TABLE        emp (
         empno      NUMBER(5) PRIMARY KEY,
         ename      VARCHAR2(15) NOT NULL,
         job        VARCHAR2(10),
         mgr        NUMBER(5),
         hiredate   DATE DEFAULT (sysdate),
         sal        NUMBER(7,2),
         comm       NUMBER(7,2),
         deptno     NUMBER(3) NOT NULL
                     CONSTRAINT dept_fkey REFERENCES dept)
             NEXT 50K
             MAXEXTENTS 10
             PCTINCREASE 25 );

In this example, integrity constraints are defined on several columns of the table. Integrity constraints are discussed in "Managing Integrity Constraints". Several segment attributes are also explicitly specified for the table. These are explained in Chapter 14, "Managing Space for Schema Objects".

Creating a Temporary Table

It is also possible to create a temporary table. The definition of a temporary table is visible to all sessions, but the data in a temporary table is visible only to the session that inserts the data into the table. You use the CREATE GLOBAL TEMPORARY TABLE statement to create a temporary table. The ON COMMIT keywords indicate if the data in the table is transaction-specific (the default) or session-specific:

This example creates a temporary table that is transaction specific:

        (startdate DATE,
         enddate DATE,
         class CHAR(20))

Indexes can be created on temporary tables. They are also temporary and the data in the index has the same session or transaction scope as the data in the underlying table.

See Also:


Parallelizing Table Creation

When you specify the AS SELECT clause when creating a table, you can utilize parallel execution. The CREATE TABLE ... AS SELECT statement contains two parts: a CREATE part (DDL) and a SELECT part (query). Oracle can parallelize both parts of the statement. The CREATE part is parallelized if one of the following is true:

The query part is parallelized if all of the following are true:

If you parallelize the creation of a table, that table then has a parallel declaration (the PARALLEL clause) associated with it. Any subsequent DML or queries on the table, for which parallelization is possible, will attempt to use parallel execution.

The following simple example parallelizes the creation of a table:

     AS SELECT * FROM scott.emp
     WHERE deptno = 10;

In this example the PARALLEL clause tells Oracle to select an optimum number of parallel execution servers when creating the table.

See Also:


Automatically Collecting Statistics on Tables

The PL/SQL package DBMS_STATS lets you generate and manage statistics for cost-based optimization. You can use this package to gather, modify, view, export, import, and delete statistics. You can also use this package to identify or name statistics that have been gathered.

You enable DBMS_STATS to automatically gather statistics for a table by specifying the MONITORING clause in the CREATE (or ALTER) TABLE statement. Then, you can effect automated statistics gathering by, for example, setting up a recurring job (perhaps by using job queues) that invokes DBMS_STATS.GATHER_TABLE_STATS with the GATHER STALE option at an appropriate interval for your application.

Monitoring tracks the approximate number of INSERT, UPDATE, and DELETE operations for the table since the last time statistics were gathered. Information about how many rows are affected is maintained in the SGA, until periodically (about every three hours) SMON incorporates the data into the data dictionary. This data dictionary information is made visible through the DBA|ALL|USER_TAB_MODIFICATIONS view. Oracle uses this view to identify tables with stale statistics.

Using the MONITORING clause and the DBMS_STATS package enables the optimizer to generate accurate execution plans, without the need for you to run regular and expensive ANALYZE statements to identify tables that have been modified. The exact mechanism for using the MONITORING clause and the DBMS_STATS package for gathering statistics is discussed in the Oracle9i Database Performance Guide and Reference.

To disable monitoring of a table, specify the NOMONITORING clause.

Altering Tables

To alter a table, the table must be contained in your schema, or you must have either the ALTER object privilege for the table or the ALTER ANY TABLE system privilege.

A table in an Oracle database can be altered for the following reasons:

You can increase the length of an existing column, or decrease it, if all existing data satisfies the new length. You can change a column from byte semantics to CHAR semantics or vice versa. You must set the initialization parameter BLANK_TRIMMING=TRUE to decrease the length of a nonempty CHAR column.

If you are modifying a table to increase the length of a column of datatype CHAR, realize that this can be a time consuming operation and can require substantial additional storage, especially if the table contains many rows. This is because the CHAR value in each row must be blank-padded to satisfy the new column length.

When altering the data block space usage parameters (PCTFREE and PCTUSED) of a table, note that new settings apply to all data blocks used by the table, including blocks already allocated and subsequently allocated for the table. However, the blocks already allocated for the table are not immediately reorganized when space usage parameters are altered, but as necessary after the change. The data block storage parameters are described in "Managing Space in Data Blocks".

When altering the transaction entry settings (INITRANS, MAXTRANS) of a table, note that a new setting for INITRANS applies only to data blocks subsequently allocated for the table, while a new setting for MAXTRANS applies to all blocks (already and subsequently allocated blocks) of a table. To better understand these transaction entry setting parameters, see "Specifying the Transaction Entry Parameters: INITRANS and MAXTRANS".

The storage parameters INITIAL and MINEXTENTS cannot be altered. All new settings for the other storage parameters (for example, NEXT, PCTINCREASE) affect only extents subsequently allocated for the table. The size of the next extent allocated is determined by the current values of NEXT and PCTINCREASE, and is not based on previous values of these parameters. Storage parameters are discussed in "Setting Storage Parameters".

You alter a table using the ALTER TABLE statement. The following statement alters the emp table. It alters the data block storage parameters, and adds a new column named bonus.

      ADD (bonus NUMBER (7,2))
      PCTFREE 30
      PCTUSED 60;

Some of the other usages of the ALTER TABLE statement are presented in the following sections:

Moving a Table to a New Segment or Tablespace

The ALTER TABLE ... MOVE statement enables you to relocate data of a nonpartitioned table into a new segment, and optionally into a different tablespace for which you have quota. This statement also allows you to modify any of the table's storage attributes, including those which cannot be modified using ALTER TABLE.

The following statement moves the emp table to a new segment specifying new storage parameters:

                NEXT 40K
                MINEXTENTS 2
                MAXEXTENTS 20
                PCTINCREASE 0 );

If the table includes LOB column(s), this statement can be used to move the table along with LOB data and LOB index segments (associated with this table) which the user explicitly specifies. If not specified, the default is to not move the LOB data and LOB index segments.

Manually Allocating Storage for a Table

Oracle dynamically allocates additional extents for the data segment of a table, as required. However, perhaps you want to allocate an additional extent for a table explicitly. For example, in an Oracle Real Application Clusters environment, an extent of a table can be allocated explicitly for a specific instance.

A new extent can be allocated for a table using the ALTER TABLE statement with the ALLOCATE EXTENT clause.

You can also explicitly deallocate unused space using the DEALLOCATE UNUSED clause of ALTER TABLE. This is described in "Deallocating Space".

See Also:

Oracle9i Real Application Clusters Administration for information about using the ALLOCATE EXTENT clause in an Oracle Real Application Clusters environment 

Dropping Columns

You can drop columns that are no longer needed from a table, including an index-organized table. This provides a convenient means to free space in a database, and avoids your having to export/import data then re-create indexes and constraints. Users require the ALTER privilege on the target table or the ALTER ANY TABLE system privilege to issue any of the drop column related statements below.

You cannot drop all columns from a table, nor can you drop columns from a table owned by SYS. Any attempt to do so results in an error.

See Also:

Oracle9i SQL Reference for information about additional restrictions and options for dropping columns from a table 

Removing Columns from Tables

When you issue an ALTER TABLE ... DROP COLUMN statement, the column descriptor and the data associated with the target column are removed from each row in the table. You can drop multiple columns with one statement. The following statements are examples of dropping columns from the emp table.

This statement drops only the sal column:


The following statement drops both the sal and comm columns:

ALTER TABLE emp DROP (sal, comm);

Marking Columns Unused

If you are concerned about the length of time it could take to drop column data from all of the rows in a large table, you can use the ALTER TABLE ... SET UNUSED statement. This statement marks one or more columns as unused, but does not actually remove the target column data or restore the disk space occupied by these columns. However, a column that is marked as unused is not displayed in queries or data dictionary views, and its name is removed so that a new column can reuse that name. All constraints, indexes, and statistics defined on the column are also removed.

To mark the sal and comm columns as unused, execute the following statement:

ALTER TABLE emp SET UNUSED (sal, comm);

You can later remove columns that are marked as unused by issuing an ALTER TABLE ... DROP UNUSED COLUMNS statement. Unused columns are also removed from the target table whenever an explicit drop of any particular column or columns of the table is issued.

The data dictionary views USER_UNUSED_COL_TABS, ALL_UNUSED_COL_TABS, or DBA_UNUSED_COL_TABS can be used to list all tables containing unused columns. The COUNT field shows the number of unused columns in the table.


OWNER                       TABLE_NAME                  COUNT
--------------------------- --------------------------- ----------
SCOTT                       EMP                                  1
1 row selected.

Removing Unused Columns

The ALTER TABLE ... DROP UNUSED COLUMNS statement is the only action allowed on unused columns. It physically removes unused columns from the table and reclaims disk space.

In the example that follows the optional keyword CHECKPOINT is specified. This option causes a checkpoint to be applied after processing the specified number of rows, in this case 250. Checkpointing cuts down on the amount of undo logs accumulated during the drop column operation to avoid a potential exhaustion of rollback segment space.


Redefining Tables Online

In highly available systems, it is occasionally necessary to redefine large "hot" tables to improve the performance of queries or DML performed against these tables. Oracle provide a mechanism to redefine tables online. This mechanism provides a significant increase in availability compared to traditional methods of redefining tables that require tables to be taken offline.

When a table is redefined online, it is accessible to DML during much of the redefinition process. The table is locked in the exclusive mode only during a very small window which is independent of the size of the table and the complexity of the redefinition.

Online table redefinition enables you to:

The mechanism for performing online redefinition is the PL/SQL package DBMS_REDEFINITION. Execute privileges on this package is granted to EXECUTE_CATALOG_ROLE. In addition to having execute privileges on this package, you must be granted the following privileges:

Several steps are involved in the redefinition process.

Steps for Online Redefinition of Tables

In order to perform an online redefinition of a table the user must perform the following steps.

  1. Verify that the table can be online redefined by invoking the DBMS_REDEFINITION.CAN_REDEF_TABLE() procedure. If the table is not a candidate for online redefinition, then this procedure raises an error indicating why the table cannot be online redefined.

  2. Create an empty interim table (in the same schema as the table to be redefined) with all of the desired attributes.

  3. Start the redefinition process by calling DBMS_REDEFINITION.START_REDEF_TABLE(), providing the following:

    • The table to be redefined

    • The interim table name

    • The column mapping.

    If the column mapping information is not supplied, then it is assumed that all the columns (with their names unchanged) are to be included in the interim table. If the column mapping is supplied, then only those columns specified explicitly in the column mapping are considered.

  4. Create any triggers, indexes, grants and constraints on the interim table. Any referential constraints involving the interim table (that is, the interim table is either a parent or a child table of the referential constraint) must be created disabled. Until the redefinition process is either completed or aborted, any trigger defined on the interim table will not execute.

    When the redefinition is completed, the triggers, constraints, indexes and grants associated with the interim table replace those on the table being redefined. The referential constraints involving the interim table (created disabled) transfer to the table being redefined and become enabled after the redefinition is complete.

  5. Execute the DBMS_REDEFINITION.FINISH_REDEF_TABLE() procedure to complete the redefinition of the table. During this procedure, the original table is locked in the exclusive mode for a very small window. This window is independent of the amount of data in the original table. Also, as part of this procedure, the following occurs:

    1. The original table is redefined such that it has all the attributes, indexes, constraints, grants and triggers of the interim table

    2. The referential constraints involving the interim table now involve the post redefined table and are enabled.

  6. Optionally rename any indexes that were created on the interim table during step 4 and that are now defined on the redefined table.

The following is the end result of the redefinition process:

Intermediate Synchronization

After the redefinition process has been started by calling START_REDEF_TABLE() and before FINISH_REDEF_TABLE() has been called, it is possible that a large number of DML statements have been executed on the original table. If you know this is the case, it is recommended that you periodically synchronize the interim table with the original table. This is done by calling the DBMS_REDEFINITION.SYNC_INTERIM_TABLE() procedure. Calling this procedure reduces the time taken by FINISH_REDEF_TABLE() to complete the redefinition process.

The small amount of time that the original table is locked during FINISH_REORG_TABLE() is independent of whether SYNC_INTERIM_TABLE() has been called.

Abort and Cleanup After Errors

In the event that an error is raised during the redefinition process, or if you choose to abort the redefinition process, call DBMS_REDEFINITION.ABORT_REDEF_TABLE(). This procedure drops temporary logs and tables associated with the redefinition process. After this procedure is called, the user can drop the interim table and its associated objects.

Example of Online Table Redefinition

This example illustrates online redefinition of nonpartitioned table emp, with columns: empno, name, salary, phone. The table is redefined as follows:

It is assumed that the DBMS_REDEFINITION.CAN_REDEF_TABLE() procedure has already been run, and that table emp is a valid candidate for redefinition.

The steps in this redefinition are illustrated below.

  1. Create an interim table int_emp.

    CREATE TABLE int_emp
           (empno       NUMBER PRIMARY KEY,
            name        VARCHAR2(100),
            sal         NUMBER,
            deptno      NUMBER DEFAULT 10)
         PARTITION BY RANGE(empno)
           (PARTITION emp1000 VALUES LESS THAN (1000) TABLESPACE tbs_1,
            PARTITION emp2000 VALUES LESS THAN (2000) TABLESPACE tbs_2);
  2. Start the redefinition process.

    DBMS_REDEFINITION.START_REDEF_TABLE('u1', 'emp', 'int_emp',
           'empno empno, name name, salary*1.10 sal');
  3. Create any triggers, indexes and constraints on int_emp. During the final step of redefinition, these are transferred back to the original table. Any referential constraints involved on int_emp should be disabled. You can define any grants associated with the interim table. These replace the grants on the original table after the redefinition.

  4. Optionally, synchronize the interim table int_emp.

    DBMS_REDEFINITION.SYNC_INTERIM_TABLE('u1', 'emp', 'int_emp');
  5. Complete the redefinition.

    DBMS_REDEFINITION.FINISH_REDEF_TABLE('u1', 'emp', 'int_emp');

    The table emp is locked in the exclusive mode only for a small window toward the end of this step. After this call the table emp is redefined such that it has all the attributes of the int_emp table.

  6. Drop the interim table.


The following restrictions apply to the online redefinition of tables:

Dropping Tables

To drop a table, the table must be contained in your schema or you must have the DROP ANY TABLE system privilege.

To drop a table that is no longer needed, use the DROP TABLE statement. The following statement drops the emp table:


If the table to be dropped contains any primary or unique keys referenced by foreign keys of other tables and you intend to drop the FOREIGN KEY constraints of the child tables, include the CASCADE option in the DROP TABLE statement, as shown below:



Before dropping a table, familiarize yourself with the consequences of doing so:

  • Dropping a table removes the table definition from the data dictionary. All rows of the table are no longer accessible.

  • All indexes and triggers associated with a table are dropped.

  • All views and PL/SQL program units dependent on a dropped table remain, yet become invalid (not usable). See "Managing Object Dependencies" for information about how Oracle manages dependencies.

  • All synonyms for a dropped table remain, but return an error when used.

  • All extents allocated for a table that is dropped are returned to the free space of the tablespace and can be used by any other object requiring new extents or new objects. All rows corresponding to a clustered table are deleted from the blocks of the cluster. Clustered tables are the subject of Chapter 18, "Managing Clusters".


Perhaps instead of dropping a table, you want to truncate it. The TRUNCATE statement provides a fast, efficient method for deleting all rows from a table, but it does not affect any structures associated with the table being truncated (column definitions, constraints, triggers, and so forth) or authorizations. The TRUNCATE statement is discussed in "Truncating Tables and Clusters".

Managing Index-Organized Tables

This section describes aspects of managing index-organized tables, and includes the following topics:

What are Index-Organized Tables

An index-organized table has a storage organization that is a variant of a primary B-tree. Unlike an ordinary (heap-organized) table whose data is stored as an unordered collection (heap), data for an index-organized table is stored in a B-tree index structure in a primary key sorted manner. Besides storing the primary key column values of an index-organized table row, each index entry in the B-tree stores the non-key column values as well.

Why use Index-Organized Tables

Index-organized tables provide fast key-based access to table data for queries involving exact match and range searches. Changes to the table data (such as adding new rows, updating rows, or deleting rows) result only in updating the index structure (because there is no separate table storage area).

Also, storage requirements are reduced because key columns are not duplicated in the table and index. The remaining non-key columns are stored in the index structure.

Index-organized tables are particularly useful when you are using applications that must retrieve data based on a primary key. Index-organized tables are also suitable for modeling application-specific index structures. For example, content-based information retrieval applications containing text, image and audio data require inverted indexes that can be effectively modeled using index-organized tables.

Differences Between Index Organized and Regular Tables

As shown in Figure 15-1, the index-organized table is somewhat similar to a configuration consisting of an ordinary table and an index on one or more of the table columns, but instead of maintaining two separate storage structures, one for the table and one for the B-tree index, the database system maintains only a single B-tree index. Also, rather than having a row's rowid stored in the index entry, the non-key column values are stored. Thus, each B-tree index entry contains <primary_key_value, non_primary_key_column_values>.

Figure 15-1 Structure of Regular Table versus an Index-Organized Table

Text description of sad81029.gif follows
Text description of the illustration sad81029.gif

Applications manipulate the index-organized table just like an ordinary table, using SQL statements. However, the database system performs all operations by manipulating the corresponding B-tree index.

See Also:


Creating Index-Organized Tables

You use the CREATE TABLE statement to create index-organized tables, but you must provide the following additional information:

The following example creates an index-organized table:

CREATE TABLE docindex(
        token char(20), 
        doc_id NUMBER,
        token_frequency NUMBER,
        token_offsets VARCHAR2(512),
        CONSTRAINT pk_docindex PRIMARY KEY (token, doc_id))

The above example shows that the ORGANIZATION INDEX qualifier specifies an index-organized table, where the key columns and non-key columns reside in an index defined on columns that designate the primary key (token, doc_id) for the table.

Index-organized tables can store object types. The following example creates an index-organized table containing a column of object type mytype:

CREATE TABLE iot (c1 NUMBER primary key, c2 mytype)

However, you cannot create an index-organized table of object types. For example, the following statement would not be valid:


See Also:

"Creating Partitioned Index-Organized Tables" for information about creating partitioned index-organized tables 

Using the AS Subquery

You can create an index-organized table using the AS subquery. Creating an index-organized table in this manner enables you to load the table in parallel by using the PARALLEL option.

The following statement creates an index-organized table (in parallel) by selecting rows from a conventional table, rt:

    AS SELECT * FROM rt;

Using the Overflow Clause

The overflow clause specified in the earlier example indicates that any non-key columns of rows exceeding 20% of the block size are placed in a data segment stored in the OVF_TBS tablespace. The key columns should fit the specified threshold.

If an update of a non-key column causes the row to decrease in size, Oracle identifies the row piece (head or tail) to which the update is applicable and rewrites that piece.

If an update of a non-key column causes the row to increase in size, Oracle identifies the piece (head or tail) to which the update is applicable and rewrites that row piece. If the update's target turns out to be the head piece, note that this piece can again be broken into 2 to keep the row size below the specified threshold.

The non-key columns that fit in the index leaf block are stored as a row head-piece that contains a ROWID field linking it to the next row piece stored in the overflow data segment. The only columns that are stored in the overflow area are those that do not fit.

Choosing and Monitoring a Threshold Value

You should choose a threshold value that can accommodate your key columns, as well as the first few non-key columns (if they are frequently accessed).

After choosing a threshold value, you can monitor tables to verify that the value you specified is appropriate. You can use the ANALYZE TABLE ... LIST CHAINED ROWS statement to determine the number and identity of rows exceeding the threshold value.

See Also:

Oracle9i SQL Reference for details about this use of the ANALYZE statement 

Using the INCLUDING clause

In addition to specifying PCTTHRESHOLD, you can use the INCLUDING clause to control which non-key columns are stored with the key columns. Oracle accommodates all non-key columns up to the column specified in the INCLUDING clause in the index leaf block, provided it does not exceed the specified threshold. All non-key columns beyond the column specified in the INCLUDING clause are stored in the overflow area.


Oracle moves all primary key columns of an indexed-organized table to the beginning of the table (in their key order), in order to provide efficient primary key based access. As an example:

                primary key(c,b))

The stored column order is: c b a d (instead of: a b c d). The last primary key column is b, based on the stored column order. The INCLUDING column can be the last primary key column (b in this example), or any non-key column (that is, any column after b in the stored column order). 

The example presented earlier can be modified to create an index-organized table where the token_offsets column value is always stored in the overflow area:

CREATE TABLE docindex(
        token CHAR(20), 
        doc_id NUMBER,
        token_frequency NUMBER,
        token_offsets VARCHAR2(512),
        CONSTRAINT pk_docindex PRIMARY KEY (token, doc_id))
        INCLUDING token_frequency
        OVERFLOW TABLESPACE ovf_tbs;

Here, only non-key columns up to token_frequency (in this case a single column only) are stored with the key column values in the index leaf block.

Using Key Compression

Creating an index-organized table using key compression enables you to eliminate repeated occurrences of key column prefix values.

Key compression breaks an index key into a prefix and a suffix entry. Compression is achieved by sharing the prefix entries among all the suffix entries in an index block. This sharing can lead to huge savings in space, allowing you to store more keys in each index block while improving performance.

You can enable key compression using the COMPRESS clause while:

You can also specify the prefix length (as the number of key columns), which identifies how the key columns are broken into a prefix and suffix entry.

CREATE TABLE iot(i INT, j INT, k INT, l INT, PRIMARY KEY (i, j, k)) 

The preceding statement is equivalent to the following statement:

CREATE TABLE iot(i INT, j INT, k INT, l INT, PRIMARY KEY(i, j, k)) 

For the list of values (1,2,3), (1,2,4), (1,2,7), (1,3,5), (1,3,4), (1,4,4) the repeated occurrences of (1,2), (1,3) are compressed away.

You can also override the default prefix length used for compression as follows:

CREATE TABLE iot(i INT, j INT, k INT, l INT, PRIMARY KEY (i, j, k)) 

For the list of values (1,2,3), (1,2,4), (1,2,7), (1,3,5), (1,3,4), (1,4,4), the repeated occurrences of 1 are compressed away.

You can disable compression as follows:


See Also:

Oracle9i Database Concepts and the Oracle9i SQL Reference for more details about key compression 

Maintaining Index-Organized Tables

Index-organized tables differ from regular tables only in physical organization; logically, they are manipulated in the same manner. You can use an index-organized table in place of a regular table in INSERT, SELECT, DELETE, and UPDATE statements.

Altering Index-Organized Tables

You can use the ALTER TABLE statement to modify physical and storage attributes for both primary key index and overflow data segments. All the attributes specified prior to the OVERFLOW keyword are applicable to the primary key index segment. All attributes specified after the OVERFLOW key word are applicable to the overflow data segment. For example, you can set the INITRANS of the primary key index segment to 4 and the overflow of the data segment INITRANS to 6 as follows:


You can also alter PCTTHRESHOLD and INCLUDING column values. A new setting is used to break the row into head and overflow tail pieces during subsequent operations. For example, the PCTHRESHOLD and INCLUDING column values can be altered for the DOCINDEX table as follows:


By setting the INCLUDING column to doc_id, all the columns that follow token_frequency and token_offsets, are stored in the overflow data segment.

For index-organized tables created without an overflow data segment, you can add an overflow data segment by using the ADD OVERFLOW clause. For example, if the DOCINDEX table did not have an overflow segment, then you can add an overflow segment as follows:


Moving (Rebuilding) Index-Organized Tables

Because index-organized tables are primarily stored in a B-tree index, you can encounter fragmentation as a consequence of incremental updates. However, you can use the ALTER TABLE ... MOVE statement to rebuild the index and reduce this fragmentation.

The following statement rebuilds the index-organized table DOCINDEX after setting its INITRANS to 10:


You can move index-organized tables with no overflow data segment online using the ONLINE option. For example, if the DOCINDEX table does not have an overflow data segment, then you can perform the move online as follows:


The following statement rebuilds the index-organized table DOCINDEX along with its overflow data segment:


And in this last statement, index-organized table IOT is moved while the LOB index and data segment for C2 are rebuilt:


Scenario: Updating the Key Column

A key column update is logically equivalent to deleting the row with the old key value and inserting the row with the new key value at the appropriate place to maintain the primary key order.

Logically, in the following example, the employee row for dept_id=20 and
e_id=10 are deleted and the employee row for dept_id=23 and e_id=10 are inserted:

UPDATE employees
    SET dept_id=23
    WHERE dept_id=20 and e_id=10;

Analyzing Index-Organized Tables

Just like conventional tables, index-organized tables are analyzed using the ANALYZE statement:


The ANALYZE statement analyzes both the primary key index segment and the overflow data segment, and computes logical as well as physical statistics for the table.

Using the ORDER BY Clause with Index-Organized Tables

If an ORDER BY clause only references the primary key column or a prefix of it, then the optimizer avoids the sorting overhead as the rows are returned sorted on the primary key columns.

For example, you create the following table:

CREATE TABLE employees (dept_id INTEGER, e_id INTEGER, e_name 

The following queries avoid sorting overhead because the data is already sorted on the primary key:

SELECT * FROM employees ORDER BY (dept_id, e_id);
SELECT * FROM employees ORDER BY (dept_id);

If, however, you have an ORDER BY clause on a suffix of the primary key column or non-primary key columns, additional sorting is required (assuming no other secondary indexes are defined).

SELECT * FROM employees ORDER BY (e_id);
SELECT * FROM employees ORDER BY (e_name);

Converting Index-Organized Tables to Regular Tables

You can convert index-organized tables to regular tables using the Oracle IMPORT or EXPORT utilities, or the CREATE TABLE ... AS SELECT statement.

To convert an index-organized table to a regular table:

Managing External Tables

Oracle allows you read-only access to data in external tables. External tables are defined as tables that do not reside in the database, and can be in any format for which an access driver is provided. By providing Oracle with metadata describing an external table, Oracle is able to expose the data in the external table as if it were data residing in a regular database table. The external data can be queried directly and in parallel using SQL.

You can, for example, select, join, or sort external table data. You can also create views and synonyms for external tables. However, no DML operations (UPDATE, INSERT, or DELETE) are possible, and no indexes can be created, on external tables.


The ANALYZE statement is not supported for gathering statistics for external tables. The DBMS_STATS package should be used for gathering statistics for external tables.

For information about using the DBMS_STATS package, see Oracle9i Database Performance Guide and Reference 

The means of defining the metadata for external tables is through the CREATE TABLE ... ORGANIZATION EXTERNAL statement. This external table definition can be thought of as a view that allows running any SQL query against external data without requiring that the external data first be loaded into the database. An access driver is the actual mechanism used to read the external data in the table.

Oracle provides an access driver for external tables. It allows the reading of data from external files using the Oracle loader technology. The ORACLE_LOADER access driver provides data mapping capabilities which are a subset of the control file syntax of SQL*Loader utility.

Oracle's external tables feature provides a valuable means for performing basic extraction, transformation, and transportation (ETT) tasks that are common for datawarehousing.

These following sections discuss the DDL statements that are supported for external tables. Only DDL statements discussed are supported, and not all clauses of these statements are supported.

Creating External Tables

You create external tables using the ORGANIZATION EXTERNAL clause of the CREATE TABLE statement. You are not in fact creating a table; that is, an external table does not have any extents associated with it. Rather, you are creating metadata in the data dictionary that enables you to access external data.

The following example creates an external table, then uploads the data to a database table.

EXAMPLE: Creating an External Table and Loading Data

The file empxt1.dat contains the following sample data:


The file empxt2.dat contains the following sample data:

7900,JAMES,CLERK,7698,03-DEC-1981,950 ,0,30 

The following SQL statements create an external table and load its data into database table scott.emp.


CREATE OR REPLACE DIRECTORY dat_dir AS '/flatfiles/data'; 
CREATE OR REPLACE DIRECTORY log_dir AS '/flatfiles/log'; 
CREATE OR REPLACE DIRECTORY bad_dir AS '/flatfiles/bad'; 


CONNECT scott/tiger; 

DROP TABLE empxt; 

CREATE TABLE empxt (empno       NUMBER(4), 
                    ename       VARCHAR2(10), 
                    job         VARCHAR2(9), 
                    mgr         NUMBER(4), 
                    hiredate    DATE, 
                    sal         NUMBER(7,2), 
                    comm        NUMBER(7,2), 
                    deptno      NUMBER(2) 
       DEFAULT DIRECTORY dat_dir 
         records delimited by newline 
         badfile bad_dir:'empxt%a_%p.bad' 
         logfile log_dir:'empxt%a_%p.log' 
         fields terminated by ',' 
         missing field values are null 
         ( empno, ename, job, mgr, 
           hiredate char date_format date mask "dd-mm-yyyy", 
           sal, comm, deptno 
       LOCATION ('empxt1.dat', 'empxt2.dat') 



The following paragraphs contain descriptive information about this example.

The first few statements in this example create the directory objects for the operating system directories that contain the data sources, and for the bad record and log files specified in the access parameters. You must also grant READ or WRITE directory object privileges, as appropriate.

The TYPE specification is given only to illustrate its use. If not specified, ORACLE_LOADER is the default access driver. The access parameters, specified in the ACCESS PARAMETERS clause, are opaque to Oracle. These access parameters are defined by the access driver, and are provided to the access driver by Oracle when the external table is accessed. See Oracle9i Database Utilities for a description of the ORACLE_LOADER access parameters.

The PARALLEL clause enables parallel query on the data sources. The granule of parallelism is by default a data source, but parallel access within a data source is implemented whenever possible. For example, if PARALLEL=3 were specified, then more than one parallel execution server could be working on a data source. But, parallel access within a data source is provided by the access driver only if all of the following conditions are met:

The REJECT LIMIT clause specifies that there is no limit on the number of errors that can occur during a query of the external data. For parallel access, this limit applies to each parallel query slave independently. For example, if REJECT LIMIT 10 is specified, each parallel query process is allowed 10 rejections. Hence, the only precisely enforced values for REJECT LIMIT on parallel query are 0 and UNLIMITED.

In this example, the INSERT INTO TABLE statement generates a dataflow from the external data source to the Oracle SQL engine where data is processed. As data is parsed by the access driver from the external table sources and provided to the external table interface, the external data is converted from its external representation to its Oracle internal data type.

See Also:

Oracle9i SQL Reference provides details of the syntax of the CREATE TABLE statement for creating external tables and specifies restrictions on the use of clauses  

Altering External Tables

You can use any of the following ALTER TABLE clauses to change the characteristics of an external table. No other clauses are permitted.

ALTER TABLE Clause  Description  Example 


Changes the reject limit 



Changes the default directory specification 

    DEFAULT DIRECTORY newemp_dir;


Allows access parameters to be changed without dropping and recreating the external table metadata 



Allows data sources to be changed without dropping and recreating the external table metadata 

    LOCATION ('empxt3.txt',


No difference from regular tables. Allows degree of parallelism to be changed. 

No new syntax 


No difference from regular tables. Allows a column to be added to an external table. 

No new syntax 


No difference from regular tables. Allows an external table column to be modified. 

No new syntax 


No difference from regular tables. Allows an external table column to be dropped. 

No new syntax 


No difference from regular tables. Allows external table to be renamed. 

No new syntax 

Dropping External Tables

For an external table, the DROP TABLE statement removes only the table metadata in the database. It has no affect on the actual data, which resides outside of the database.

System and Object Privileges for External Tables

System and object privileges for external tables are a subset of those for regular table. Only the following system privileges are applicable to external tables:

Only the following object privileges are applicable to external tables:

However, object privileges associated with a directory are:

For external tables, READ privileges are required on directory objects that contain data sources, while WRITE privileges are required for directory objects containing bad, log, or discard files.

Viewing Information About Tables

The following views allow you to access information about tables.

View  Description 




DBA view describes all relational tables in the database. ALL view describes all tables accessible to the user. USER view is restricted to tables owned by the user. Some columns in these views contain statistics that are generated by the DBMS_STATS package or ANALYZE statement. 




These views describe the columns of tables, views, and clusters in the database. Some columns in these views contain statistics that are generated by the DBMS_STATS package or ANALYZE statement. 




These views describe all relational and object tables in the database. Object tables are not specifically discussed in this book. 




These views display comments for tables and views. Comments are entered using the COMMENT statement. 




These views display comments for table and view columns. Comments are entered using the COMMENT statement. 




These views list the specific attributes of external tables in the database.  




These views list the data sources for external tables. 




These views describe histograms on tables and views. 




These views provide column statistics and histogram information extracted from the related TAB_COLUMNS views. 




These views describe tables that have been modified since the last time table statistics were gathered on them. The views are populated only for tables with the MONITORING attribute. They are not populated immediately, but after a time lapse (usually 3 hours). 




These views list tables with unused columns, as marked by the ALTER TABLE ... SET UNUSED statement. 




These views list tables that have partially completed DROP COLUMN operations. These operations could be incomplete because the operation was interrupted by the user or a system crash. 

See Also:


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

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

Master Index