Oracle® Database Administrator's Guide 11g Release 2 (11.2) Part Number E25494-02 |
|
|
PDF · Mobi · ePub |
This section discusses guidelines for managing indexes and contains the following topics:
Consider Costs and Benefits of Coalescing or Rebuilding Indexes
Consider Cost Before Disabling or Dropping Constraints
See Also:
Oracle Database Concepts for conceptual information about indexes and indexing, including descriptions of the various indexing schemes offered by Oracle
Oracle Database Performance Tuning Guide and Oracle Database Data Warehousing Guide for information about bitmap indexes
Oracle Database Data Cartridge Developer's Guide for information about defining domain-specific operators and indexing schemes and integrating them into the Oracle Database server
Data is often inserted or loaded into a table using either the SQL*Loader or an import utility. It is more efficient to create an index for a table after inserting or loading the data. If you create one or more indexes before loading data, the database then must update every index as each row is inserted.
Creating an index on a table that already has data requires sort space. Some sort space comes from memory allocated for the index creator. The amount for each user is determined by the initialization parameter SORT_AREA_SIZE
. The database also swaps sort information to and from temporary segments that are only allocated during the index creation in the user's temporary tablespace.
Under certain conditions, data can be loaded into a table with SQL*Loader direct-path load and an index can be created as data is loaded.
See Also:
Oracle Database Utilities for information about using SQL*Loader for direct-path loadUse the following guidelines for determining when to create an index:
Create an index if you frequently want to retrieve less than 15% of the rows in a large table. The percentage varies greatly according to the relative speed of a table scan and how the distribution of the row data in relation to the index key. The faster the table scan, the lower the percentage; the more clustered the row data, the higher the percentage.
To improve performance on joins of multiple tables, index columns used for joins.
Note:
Primary and unique keys automatically have indexes, but you might want to create an index on a foreign key.Small tables do not require indexes. If a query is taking too long, then the table might have grown from small to large.
Columns That Are Suitable for Indexing
Some columns are strong candidates for indexing. Columns with one or more of the following characteristics are candidates for indexing:
Values are relatively unique in the column.
There is a wide range of values (good for regular indexes).
There is a small range of values (good for bitmap indexes).
The column contains many nulls, but queries often select all rows having a value. In this case, use the following phrase:
WHERE COL_X > -9.99 * power(10,125)
Using the preceding phrase is preferable to:
WHERE COL_X IS NOT NULL
This is because the first uses an index on COL_X
(assuming that COL_X
is a numeric column).
Columns That Are Not Suitable for Indexing
Columns with the following characteristics are less suitable for indexing:
There are many nulls in the column and you do not search on the not null values.
LONG
and LONG
RAW
columns cannot be indexed.
You can create unique or non-unique indexes on virtual columns.
The order of columns in the CREATE
INDEX
statement can affect query performance. In general, specify the most frequently used columns first.
If you create a single index across columns to speed up queries that access, for example, col1
, col2
, and col3
; then queries that access just col1
, or that access just col1
and col2
, are also speeded up. But a query that accessed just col2
, just col3
, or just col2
and col3
does not use the index.
A table can have any number of indexes. However, the more indexes there are, the more overhead is incurred as the table is modified. Specifically, when rows are inserted or deleted, all indexes on the table must be updated as well. Also, when a column is updated, all indexes that contain the column must be updated.
Thus, there is a trade-off between the speed of retrieving data from a table and the speed of updating the table. For example, if a table is primarily read-only, having more indexes can be useful; but if a table is heavily updated, having fewer indexes could be preferable.
Consider dropping an index if:
It does not speed up queries. The table could be very small, or there could be many rows in the table but very few index entries.
The queries in your applications do not use the index.
The index must be dropped before being rebuilt.
See Also:
"Monitoring Index Usage"Index segment creation is deferred when the associated table defers segment creation. This is because index segment creation reflects the behavior of the table it is associated with.
See Also:
"Understand Deferred Segment Creation" for further informationEstimating the size of an index before creating one can facilitate better disk space planning and management. You can use the combined estimated size of indexes, along with estimates for tables, the undo tablespace, and redo log files, to determine the amount of disk space that is required to hold an intended database. From these estimates, you can make correct hardware purchases and other decisions.
Use the estimated size of an individual index to better manage the disk space that the index uses. When an index is created, you can set appropriate storage parameters and improve I/O performance of applications that use the index. For example, assume that you estimate the maximum size of an index before creating it. If you then set the storage parameters when you create the index, fewer extents are allocated for the table data segment, and all of the index data is stored in a relatively contiguous section of disk space. This decreases the time necessary for disk I/O operations involving this index.
The maximum size of a single index entry is approximately one-half the data block size.
Storage parameters of an index segment created for the index used to enforce a primary key or unique key constraint can be set in either of the following ways:
In the ENABLE
... USING
INDEX
clause of the CREATE
TABLE
or ALTER
TABLE
statement
In the STORAGE
clause of the ALTER
INDEX
statement
Indexes can be created in any tablespace. An index can be created in the same or different tablespace as the table it indexes. If you use the same tablespace for a table and its index, it can be more convenient to perform database maintenance (such as tablespace or file backup) or to ensure application availability. All the related data is always online together.
Using different tablespaces (on different disks) for a table and its index produces better performance than storing the table and index in the same tablespace. Disk contention is reduced. But, if you use different tablespaces for a table and its index and one tablespace is offline (containing either data or index), then the statements referencing that table are not guaranteed to work.
You can parallelize index creation, much the same as you can parallelize table creation. Because multiple processes work together to create the index, the database can create the index more quickly than if a single server process created the index sequentially.
When creating an index in parallel, storage parameters are used separately by each query server process. Therefore, an index created with an INITIAL
value of 5M and a parallel degree of 12 consumes at least 60M of storage during index creation.
See Also:
Oracle Database VLDB and Partitioning Guide for information about using parallel executionYou can create an index and generate minimal redo log records by specifying NOLOGGING
in the CREATE INDEX
statement.
Note:
Because indexes created usingNOLOGGING
are not archived, perform a backup after you create the index.Creating an index with NOLOGGING
has the following benefits:
Space is saved in the redo log files.
The time it takes to create the index is decreased.
Performance improves for parallel creation of large indexes.
In general, the relative performance improvement is greater for larger indexes created without LOGGING
than for smaller ones. Creating small indexes without LOGGING
has little effect on the time it takes to create an index. However, for larger indexes the performance improvement can be significant, especially when you are also parallelizing the index creation.
Use unusable or invisible indexes when you want to improve the performance of bulk loads, test the effects of removing an index before dropping it, or otherwise suspend the use of an index by the optimizer.
An unusable index is ignored by the optimizer and is not maintained by DML. One reason to make an index unusable is to improve bulk load performance. (Bulk loads go more quickly if the database does not need to maintain indexes when inserting rows.) Instead of dropping the index and later re-creating it, which requires you to recall the exact parameters of the CREATE
INDEX
statement, you can make the index unusable, and then rebuild it.
You can create an index in the unusable state, or you can mark an existing index or index partition unusable. In some cases the database may mark an index unusable, such as when a failure occurs while building the index. When one partition of a partitioned index is marked unusable, the other partitions of the index remain valid.
An unusable index or index partition must be rebuilt, or dropped and re-created, before it can be used. Truncating a table makes an unusable index valid.
Beginning with Oracle Database 11g Release 2, when you make an existing index unusable, its index segment is dropped.
The functionality of unusable indexes depends on the setting of the SKIP_UNUSABLE_INDEXES
initialization parameter. When SKIP_UNUSABLE_INDEXES
is TRUE
(the default), then:
DML statements against the table proceed, but unusable indexes are not maintained.
DML statements terminate with an error if there are any unusable indexes that are used to enforce the UNIQUE
constraint.
For nonpartitioned indexes, the optimizer does not consider any unusable indexes when creating an access plan for SELECT
statements. The only exception is when an index is explicitly specified with the INDEX()
hint.
For a partitioned index where one or more of the partitions are unusable, the optimizer does not consider the index if it cannot determine at query compilation time if any of the index partitions can be pruned. This is true for both partitioned and nonpartitioned tables. The only exception is when an index is explicitly specified with the INDEX()
hint.
When SKIP_UNUSABLE_INDEXES
is FALSE
, then:
If any unusable indexes or index partitions are present, any DML statements that would cause those indexes or index partitions to be updated are terminated with an error.
For SELECT
statements, if an unusable index or unusable index partition is present but the optimizer does not choose to use it for the access plan, the statement proceeds. However, if the optimizer does choose to use the unusable index or unusable index partition, the statement terminates with an error.
Beginning with Oracle Database 11g Release 1, you can create invisible indexes or make an existing index invisible. An invisible index is ignored by the optimizer unless you explicitly set the OPTIMIZER_USE_INVISIBLE_INDEXES
initialization parameter to TRUE
at the session or system level. Unlike unusable indexes, an invisible index is maintained during DML statements. Although you can make a partitioned index invisible, you cannot make an individual index partition invisible while leaving the other partitions visible.Using invisible indexes, you can do the following:
Test the removal of an index before dropping it.
Use temporary index structures for certain operations or modules of an application without affecting the overall application.
Improper sizing or increased growth can produce index fragmentation. To eliminate or reduce fragmentation, you can rebuild or coalesce the index. But before you perform either task weigh the costs and benefits of each option and choose the one that works best for your situation. Table 21-1 is a comparison of the costs and benefits associated with rebuilding and coalescing indexes.
Table 21-1 Costs and Benefits of Coalescing or Rebuilding Indexes
Rebuild Index | Coalesce Index |
---|---|
Quickly moves index to another tablespace |
Cannot move index to another tablespace |
Higher costs: requires more disk space |
Lower costs: does not require more disk space |
Creates new tree, shrinks height if applicable |
Coalesces leaf blocks within same branch of tree |
Enables you to quickly change storage and tablespace parameters without having to drop the original index. |
Quickly frees up index leaf blocks for use. |
In situations where you have B-tree index leaf blocks that can be freed up for reuse, you can merge those leaf blocks using the following statement:
ALTER INDEX vmoore COALESCE;
Figure 21-1 illustrates the effect of an ALTER INDEX COALESCE
on the index vmoore
. Before performing the operation, the first two leaf blocks are 50% full. Therefore, you have an opportunity to reduce fragmentation and completely fill the first block, while freeing up the second.
Because unique and primary keys have associated indexes, you should factor in the cost of dropping and creating indexes when considering whether to disable or drop a UNIQUE
or PRIMARY KEY
constraint. If the associated index for a UNIQUE
key or PRIMARY KEY
constraint is extremely large, you can save time by leaving the constraint enabled rather than dropping and re-creating the large index. You also have the option of explicitly specifying that you want to keep or drop the index when dropping or disabling a UNIQUE
or PRIMARY KEY
constraint.
See Also:
"Managing Integrity Constraints"