使用OR时忽略Oracle SQL索引

时间:2016-02-11 08:05:28

标签: sql oracle indexing multiple-columns

我有一张有2列和大约800万行的表格。 equip_no和op_id。这些列在单个索引中单独和一起索引。两者的价值几乎都是独一无二的。

我在执行查询时发现,在2列上使用AND,索引使用得很好,性能很好,800万行,次秒响应时间。

select *
from asset_table
where equip_no like 'something%'
AND op_id like 'somethingElse%'

但是,如果我采用完全相同的查询并将AND更改为OR,我的计划中突然以一个TABLE ACCESS FULL结束,查询需要20或30秒。

select *
from asset_table
where equip_no like 'something%'
OR op_id like 'somethingElse%'    

如果有帮助,我的Oracle版本如下。

Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi

所以我并不是全新的索引,但我从来没有真正专注于它们。我想知道这是否是已知的行为,还是我没有做我应该做的事情。我使用以下命令创建索引...

create index IDX_asset_TABLE_EQ_OPID
on asset_table(equip_no, op_id)

create index IDX_asset_TABLE_EQ
on asset_table(equip_no)

create index IDX_asset_TABLE_OPID
on asset_table(op_id)

感谢任何帮助。我已经搜索了很长时间,到目前为止没有运气。

由于

3 个答案:

答案 0 :(得分:1)

检查您的表格,列和索引统计信息以及解释计划中的信息。没有这些信息,很难给出一个好的答案。但我可以解释基础知识。

'和'使您的查询更具选择性(返回的行数更少),这是索引的优点。

'或'使您的查询选择性降低(返回更多行),这使得全表扫描看起来更便宜。

示例:

 born in june and female  (1/12 * 1/2) = 1/24 of the rows 
 born in june or  female  (1/12 + 1/2) = 7/12 of the rows

答案 1 :(得分:0)

我认为oracle应该使用称为“或扩展”的机制。但可能你没有表和索引的统计数据。 您可以将查询重写为3 union all或应用提示“/*+ use_concat */'。提示强制优化器使用union all。

select  /*+ use_concat */ *
from asset_table
where equip_no like 'something%'
OR op_id like 'somethingElse%'    

答案 2 :(得分:0)

感谢上面的回复。虽然不是完整的解决方案,但他们提供的信息促使我朝着正确的方向前进。

最终解决方案涉及理解为什么 - 或者看起来很昂贵 - 并提供一个提示。 我尝试了建议的提示/ * + use_concat /并且它有所帮助。可衡量但不是很好。 在借用朋友优化器之后,以下提示提供了最佳的整体性能。 / + INDEX(ASSET_TABLE)* /

您可能已经猜到我提供的代码段是更大查询的一部分。该片段是关键的性能限制因素,它提供了对最终结果的选择性,其余部分仅填充了字段。

感谢您的回复。

的Darren