oracle - 索引范围扫描 vs 索引跳过扫描 vs 索引快速全扫描

标签 oracle indexing database-administration

我有 table

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

我有两个索引,一个是 (id1,id2) 上的复合索引 indx1indx2(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 运行多个索引范围扫描的一个功能?

最佳答案

我建议您熟悉此链接: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);

关于oracle - 索引范围扫描 vs 索引跳过扫描 vs 索引快速全扫描,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19059444/

相关文章:

php - PDO 无法返回last_insert_id

php - 在 Codeigniter 的库中连接另一个数据库

python - Pandas - 在数据帧 : ValueError: cannot reindex from a duplicate axis 中追加字符串

wordpress - 给予index.html优先于index.php

sql-server - 更改身份列上的填充因子是否会影响合并复制?

mysql - pid 文件参数在 my.cnf 中被忽略

java - 使用oracle webservices代理时出现错误: java. lang.NoClassDefFoundError: org/codehaus/stax2/XMLInputFactory2

sql - 表声明中的列别名

oracle - 以 SYSDBA 身份运行 Oracle IMP

mysql - 在使用 'OR' 时不使用索引键