Oracle 不使用不可见索引,尽管有提示

Oracle does not use invisible index despite of hint

我似乎弄乱了索引提示语法,但我已经尝试了所有我能想到的schema/table/index-combination。

table 以及索引与 SYS 用户(这是我正在测试索引提示的用户)处于不同的模式

这是没有提示的语句

select id from car.event where dat < sysdate and type != 0

这些是我尝试在 car 模式

中为索引 dat_type 实现索引提示的方法
select /*+ index(car.event car.dat_type) */ id from car.event where dat < sysdate and type != 0
select /*+ index(event car.dat_type) */ id from car.event where dat < sysdate and type != 0
select /*+ index(car.event dat_type) */ id from car.event where dat < sysdate and type != 0
select /*+ index(event dat_type) */ id from car.event where dat < sysdate and type != 0
select /*+ index(event (dat, type)) */ id from car.event where dat < sysdate and type != 0

所以对于这五个语句,我查找了五个不同的 sql_ids 并查看了执行计划,如下所示

select * from table(dbms_xplan.display_awr([sql_id]));

但是其中none显示了索引的使用情况。它们都使用 20 的 DoP。我是否必须明确禁用并行性才能使用索引?或者有人可以更正我的索引提示的语法吗?

这是dat_type索引的定义

create index car.dat_type on car.event(dat, type) online;

编辑:索引设置为不可见,这样其他语句就不能使用索引,但我想通过索引提示显式使用它。以我的理解,隐形不应该成为索引提示的问题。如有不妥请指正

您忘记在示例中选择 ID 列。您必须指定架构名称和没有架构的索引 "dot".

你可以这样做:

select /*+ index(car dat_type) */ id from car.event where dat < sysdate and type != 0

select /*+ index(car, dat_type) */ id from car.event where dat < sysdate and type != 0

这并不总是强制索引,但正确的语法是一个好的开始。有时基于成本的优化器 (CBO) 很顽固...

我没有真正使用过不可见索引,但我阅读文档表明仅凭提示无法使用它们。您必须在系统或会话级别使用初始化参数:

An invisible index is an index that is ignored by the optimizer unless you explicitly set the OPTIMIZER_USE_INVISIBLE_INDEXES initialization parameter to TRUE at the session or system level.

(来自 https://docs.oracle.com/cd/B28359_01/server.111/b28310/indexes003.htm#ADMIN12317

根据我对 visible 索引的测试,提示中的这些选项都按预期工作:

/*+ index(event) */
/*+ index(event dat_type) */

可能其他替代方案也可以,但这些是最简单的,而且效果很好。问题不在您的索引提示语法中;就是你需要另一个步骤来启用不可见索引。

编辑添加:正如OP发现的那样,启用不可见索引的另一种方法是USE_INVISIBLE_INDEX提示。要仅通过提示完成 OP 想要的操作,必须指定 USE_INVISIBLE_INDEX 提示和 INDEX 提示。

我偶然发现了 this article,这表明实际上不可能仅通过索引提示来使用不可见索引。但是,不可见索引可以与附加提示一起使用 USE_INVISIBLE_INDEXES.

这就是我让它工作的方式:

select /*+ use_invisible_indexes index(car dat_type) */ id from car.event where dat < sysdate and type != 0