Oracle Composite Index

Source: Internet
Author: User
Tags create index sorts

--composite index, also known as Union Index, combined index.

In Oracle, you can create a composite index, which is an index that contains two or more columns at the same time. Oracle has the following features with regard to the use of composite indexes:

1. When using a rule-based optimizer (RBO), the index is used only if the leading column of the combined index (that is, the first column) appears in the WHERE clause of the SQL statement;

2. The cost-based optimizer (CBO) before using oracle9i is likely to be used only if the lead of the combined index is listed in the WHERE clause of the SQL statement now, depending on the cost of using the index and the cost of using a full table scan that the optimizer calculates. Oracle automatically chooses the low cost access path (see Test 1 and Test 2 below);

3. From oracle9i onwards, Oracle introduced a new index scan Method-index skip scan (index skipping scan), which can only be used by a cost-based optimizer (CBO). This way, when the SQL statement's WHERE clause does not have a leading column for the combined index, and the first column of the index has a high repeat rate, Oracle scans the combined index using that method (see test 3 below);

--About index jump scan meaning understanding, an article says: "It's like skipping its leading column while scanning the index, starting scanning directly from the non-leading column of the index", article link: http://book.51cto.com/art/201312/422441.htm

4. The Oracle optimizer sometimes makes the wrong choice, because it is "smart" and not as well as our SQL statement writers are more aware of the distribution of data in the table, in which case, by using hints (hint), we can help the Oracle optimizer to make better choices.

For the first three cases, we tested each of the following:

We created the test table T, which is derived from Oracle's Data dictionary table all_objects, and the structure of the table T is as follows:

Sql> desc T

is the name empty? Type

----------------------------------------- -------- ---------------------

OWNER not NULL VARCHAR2 (30)

object_name not NULL VARCHAR2 (30)

Subobject_name VARCHAR2 (30)

OBJECT_ID not NULL number

DATA_OBJECT_ID number

Object_type VARCHAR2 (18)

CREATED not NULL DATE

Last_ddl_time not NULL DATE

TIMESTAMP VARCHAR2 (19)

STATUS VARCHAR2 (7)

Temporary VARCHAR2 (1)

Generated VARCHAR2 (1)

Secondary VARCHAR2 (1)


The data in the table is distributed as follows:

Sql> Select Object_type,count (*) from the T Group by Object_type;

Object_type COUNT (*)

------------------ ----------

CONSUMER GROUP 20

Evaluation Context 10

FUNCTION 360

INDEX 69

LIBRARY 20

LOB 20

OPERATOR 20

PACKAGE 1210

PROCEDURE 130

Synonym 16100

TABLE 180

TYPE 2750

VIEW 8600

13 rows have been selected.

Sql> Select COUNT (*) from T;

COUNT (*)

----------

29489

We created the following index on table T and analyzed it:

Sql> CREATE index indx_t on T (object_type,object_name);

The index has been created.

sql> ANALYZE TABLE T COMPUTE STATISTICS

2 for TABLE

3 for all INDEXES

4 for all INDEXED COLUMNS

5/

The table is parsed.

Now let's write a few SQL statements to test the Oracle Optimizer's choice of Access path:

Test 1)

Sql> Set Autotrace traceonly

Sql> SELECT * from T WHERE object_type= ' LOB ';

20 rows have been selected.

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT optimizer=choose (cost=22 card=20 bytes=1740)

1 0 TABLE ACCESS (by INDEX ROWID) of ' T ' (cost=22 card=20 bytes=1740)

2 1 INDEX (RANGE SCAN) of ' indx_t ' (non-unique) (cost=2 card=20)

As we expected, Oracle wisely selected index scans because of the use of the leading columns of the combined index and access to a small number of records in the table. So, what kind of Access path will Oracle choose if we have access to a large amount of data in the table? Take a look at the following test:


Test 2)

Sql> SELECT * from T WHERE object_type= ' synonym ';

16100 rows have been selected.

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT optimizer=choose (cost=38 card=16100 bytes=1400700)

1 0 TABLE ACCESS (full) ' T ' (cost=38 card=16100 bytes=1400700)

Statistics

----------------------------------------------------------

0 Recursive calls

0 db Block gets

1438 consistent gets

Physical Reads

0 Redo Size

941307 Bytes sent via sql*net to client

12306 bytes received via sql*net from client

1075 sql*net roundtrips To/from Client

0 Sorts (memory)

0 Sorts (disk)

16100 rows processed

Obviously, even with the leading columns of the combined index, Oracle chose to use the full table scan without the index because of access to a large amount of data in the table, because the optimizer considered the cost of a full table scan to be lower, but the fact is not true. We force it to use the index by adding a hint (hint):


Sql> select/**//*+ INDEX (t indx_t) * * from T WHERE object_type= ' synonym ';

16100 rows have been selected.

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT optimizer=choose (cost=16180 card=16100 bytes=1400700)

1 0 TABLE ACCESS (by INDEX ROWID) of ' T ' (cost=16180 card=16100 bytes=1400700)

2 1 INDEX (RANGE SCAN) of ' indx_t ' (non-unique) (cost=80 card=16100)

Statistics

----------------------------------------------------------

0 Recursive calls

0 db Block gets

17253 consistent gets

Physical Reads

0 Redo Size

298734 Bytes sent via sql*net to client

12306 bytes received via sql*net from client

1075 sql*net roundtrips To/from Client

0 Sorts (memory)

0 Sorts (disk)

16100 rows processed

As you can see from the results above, the use of indexes does result in higher execution costs when accessing large amounts of data, as can be seen from the logical reads (consistent gets) of the statistics section. The number of logical reads that are caused by using an index is 10 times times more than the logical reads that result from using an index. Therefore, Oracle has wisely chosen a full table scan rather than an index scan.

Let's look at the case where there is no index leading column in the WHERE clause:


Test 3)


Sql> select * from t where object_name= ' DEPT ';

10 rows have been selected.

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT optimizer=choose (cost=29 card=14 bytes=1218)

1 0 TABLE ACCESS (by INDEX ROWID) of ' T ' (cost=29 card=14 bytes=1218)

2 1 INDEX (SKIP SCAN) of ' indx_t ' (non-unique) (cost=14 card=14)

Statistics

----------------------------------------------------------

0 Recursive calls

0 db Block gets

Consistent gets

0 physical Reads

0 Redo Size

1224 Bytes sent via sql*net to client

503 Bytes received via sql*net from client

2 sql*net roundtrips To/from Client

0 Sorts (memory)

0 Sorts (disk)

Ten rows processed

Let's take a look. If you do not use an index jump scan, the cost of the statement:

Sql> select/**//*+ no_index (t indx_t) * from T where object_name= ' DEPT ';

10 rows have been selected.

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT optimizer=choose (cost=38 card=14 bytes=1218)

1 0 TABLE ACCESS (full) ' T ' (cost=38 card=14 bytes=1218)

Statistics

----------------------------------------------------------

0 Recursive calls

0 db Block gets

375 consistent gets

Physical Reads

0 Redo Size

1224 Bytes sent via sql*net to client

503 Bytes received via sql*net from client

2 sql*net roundtrips To/from Client

0 Sorts (memory)

0 Sorts (disk)

Ten rows processed

As we expected, the logical reads (375) that are caused by not using an index are indeed more than 10 times times more logical than using an index (24).

To continue with our tests, now let's look at how Oracle does not choose to use indexes:


--This article from: http://www.cnblogs.com/rootq/archive/2008/10/19/1314669.html, and made a few changes.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.