2

我有桌子

test_A(
    id1 number,
    id2 number,
    id3 number,
    name varchar2(10),
    create_dt date
)

我有两个索引和 一个复合索引indx1。现在当我查询这个表时(id1,id2)indx2(id3)test_A

select * from test_A where id2=123 and 
create_dt=(select max(create_dt) from test_A where test_A.id2=id2);

我为上面的 SQL 运行了解释计划,它正在使用“索引跳过扫描”。如果我使用索引快速完整扫描和所有成本在其上创建另一个索引,create_dt并且 %cpu 显示高于使用索引跳过扫描的计划。在创建索引后,它也在使用索引范围扫描create_dt

我无法得出哪个应该可以的结论?我需要创建另一个索引create_dt还是索引跳过扫描好?我相信索引跳过是 Oracle 运行多个索引范围扫描的功能?

4

1 回答 1

3

我建议您熟悉此链接:http
://docs.oracle.com/cd/E16655_01/server.121/e15858/tgsql_optop.htm#CHDFJIJA 它与 Oracle 12c 相关,但是了解如何操作非常有用oracle 在所有 DBMS 版本中使用不同的索引访问路径。


您的子查询不明确:

select max(create_dt) from test_A where test_A.id2=id2

test_A.id2 和 id2 都引用同一个 test_A.id2,查询等价于:

select * from test_A where id2=123 and 
create_dt=(select max(create_dt) from test_A where id2=id2);

或者简单地说:

select * from test_A where id2=123 and 
create_dt=(select max(create_dt) from test_A where id2 is not null);



我想你想要这样的东西:

select * from test_A where id2=123 and 
create_dt=(select max(create_dt) 
           from test_A ALIAS 
           where test_A.id2=ALIAS.id2);

对于上面的查询,id2+create_dt 上的复合索引最有可能给出最好的结果,试试吧:

CREATE INDEX index_name ON test_A( id2, create_dt);
于 2013-09-28T13:04:17.377 回答