如果列在两个索引之间是通用的,我在oracle中没有获得索引选择行为。
以下是示例代码:
create table emp
(id number,
dpt number);
我在这张桌子上有两个索引:
create unique index ind1 on emp (id);
create unique index ind2 on emp (id,dpt);
这是我使用的数据:
Insert into EMP (ID,DPT) values (1,2);
Insert into EMP (ID,DPT) values (2,2);
Insert into EMP (ID,DPT) values (3,2);
当我根据某些过滤条件(例如
)获取数据时select * from emp where id =2;
根据解释计划使用IND2
当我使用范围查询IND1时:
select * from emp where id > 2;
我没有得到关于此类索引行为的任何具体原因。
这里是否使用任何特定逻辑来决定在每个查询中使用哪个索引。
答案 0 :(得分:0)
对于单个查找,复合索引上的INDEX RANGE SCAN
比它便宜
单列索引需要INDEX UNIQUE SCAN
和TABLE ACCESS BY INDEX ROWID
。复合索引可能更大并且具有更多分支,但每个叶包含结果所需的所有值。访问该额外分支比访问整个不同的数据结构(表段)便宜。
这是一个稍大的示例架构。问题中的DDL很有用,但要真正理解这些问题,添加样本数据并显示如何收集统计信息非常重要。
create table emp(id number,dpt number);
create unique index ind1 on emp (id);
create unique index ind2 on emp (id,dpt);
insert into emp select level,level from dual connect by level <= 100000;
begin
dbms_stats.gather_table_stats(user, 'emp');
end;
/
在问题中,默认计划使用IND2。
explain plan for select * from emp where id=2;
select * from table(dbms_xplan.display);
Plan hash value: 1519675770
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 10 | 2 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IND2 | 1 | 10 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("ID"=2)
提示显示IND1计划的样子。请注意,现在计划必须同时访问索引和表。
explain plan for select /*+ index(emp ind1) */ * from emp where id =2;
select * from table(dbms_xplan.display);
Plan hash value: 2624671090
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 10 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 10 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | IND1 | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=2)
这只回答了第一个问题。我对第二个问题没有很好的解释。如果您可以修改示例数据以重新创建该场景,我们可以对其进行调查。