What Indexes Are For : OCA 11g SQL Fundamentals
星期三, 二月 10th, 2010Indexes are part of the constraint mechanism. If a column (or a group of columns) is marked as a table’s primary key, then every time a row is inserted into the table,Oracle must check that a row with the same value in the primary key does not already exist. If the table has no index on the column(s), the only way to do this is to scan right through the table, checking every row. While this might be acceptable for a table of only a few rows, for a table with thousands or millions (or billions) of rows, this is not feasible. An index gives (near) immediate access to key values, so the check for existence can be made virtually instantaneously. When a primary key constraint is defined, Oracle will automatically create an index on the primary key column(s), if one does not exist already.
A unique constraint also requires an index. The difference from a primary key constraint is that the column(s) of the unique constraint can be left null, perhaps in many rows. This does not affect the creation and use of the index: nulls do not go into the B*Tree indexes, as described in the next section, “Types of Index.”
Foreign key constraints are enforced by indexes, but the index must exist on the parent table, not necessarily on the table for which the constraint is defined. A foreign key constraint relates a column in the child table to the primary key or to a unique key in the parent table. When a row is inserted in the child table, Oracle will do a lookup on the index on the parent table to confirm that there is a matching row before permitting the insert. However, you should always create indexes on the foreign key columns within the child table for performance reasons: a DELETE on the parent table will be much faster if Oracle can use an index to determine whether there are any rows in the child table referencing the row that is being deleted.
Indexes are critical for performance. When executing any SQL statement that includes a WHERE clause, Oracle has to identify which rows of the table are to be selected or modified. If there is no index on the column(s) referenced in the WHERE clause, the only way to do this is with a full table scan. A full table scan reads every row of the table, in order to find the relevant rows. If the table has billions of rows, this can take hours. If there is an index on the relevant column(s), Oracle can search the index instead. An index is a sorted list of key values, structured in a manner that makes the search very efficient. With each key value is a pointer to the row in the table. Locating relevant rows via an index lookup is far faster than using a full table scan, if the table is over a certain size and the proportion of the rows to be retrieved is below a certain value. For small tables, or for a WHERE clause that will retrieve a large fraction of the table’s rows, a full table scan will be quicker: you can (usually) trust Oracle to make the correct decision, based on information the database gathers about the tables and the rows within them.
A second circumstance where indexes can be used is for sorting. A SELECT statement that includes the ORDER BY, GROUP BY, or UNION keywords (and a few others) must sort the rows into order—unless there is an index, which can return the rows in the correct order without needing to sort them first.
A third circumstance when indexes can improve performance is when tables are joined, but again Oracle has a choice: depending on the size of the tables and the memory resources available, it may be quicker to scan tables into memory and join them there, rather than use indexes. The nested loop join technique passes through one table using an index on the other table to locate the matching rows: this is usually a disk-intensive operation. A hash join technique reads the entire table into memory, converts it into a hash table, and uses a hashing algorithm to locate matching rows; this is more memory and CPU intensive. A sort merge join sorts the tables on the join column then merges them together: this is often a compromise between disk, memory, and CPU resources. If there are no indexes, then Oracle is severely limited in the join techniques available.
