日期:2014-05-16 浏览次数:20723 次
在表上建复合索引是常见的事情,那索引中键值的顺序是什么呢?通过下面的实验可以得出三个结论:
--制造实验数据,并收集统计信息
SQL> create table test as select * from dba_objects;
SQL> create index ind_id_owner on test(object_id,owner);
SQL> create index ind_owner_id on test(owner,object_id);
SQL> exec dbms_stats.gather_table_stats(user,'test',cascade=>true);
SQL> select count(distinct owner) owner_count, count(distinct object_id) id_count, count(*) from test;
OWNER_COUNT ID_COUNT COUNT(*)
----------- ---------- ----------
25 50583 50584
SQL> set autotrace traceonly
1. 如果是等值查询,那字段无先后之分,结合着索引的存储结构,索引存储的是键值和rowid,复合索引就是存储两个键值,如果是等值查询,可以看作是一个值,跟单个字段索引查询一样。
SQL> select /*+index(test,ind_id_owner)*/* from test where owner ='TEST' and object_id =52623;
执行计划
----------------------
Plan hash value: 1096520809
--------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 93 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 93 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_ID_OWNER | 1 | | 1 (0)| 00:00:01 |
--------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"=52623 AND "OWNER"='TEST')
统计信息
----------------------
1 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
1199 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select /*+index(test,ind_owner_id)*/* from test where owner ='TEST' and object_id =52623;
执行计划
----------------------
Plan hash value: 724495818
--------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 93 | 2