我有一张有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)
感谢任何帮助。我已经搜索了很长时间,到目前为止没有运气。
由于
答案 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