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
我似乎弄乱了索引提示语法,但我已经尝试了所有我能想到的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