1

我在 Oracle DB 中有一个表,它有两个索引,一个用于表字段 A,一个用于表字段 B。现在我需要选择在字段 A 中具有特定值或在字段 B 中具有另一个特定值的所有记录。

为了使用索引,我当然可以在字段 A 上进行一个 SELECT,然后在字段 B 上进行另一个 SELECT。所以我可以确保两个索引都被使用。

但是,我宁愿使用一个 SELECT 并且 WHERE 子句中的两个字段都与 OR 连接。在这种情况下以及如上所述的设置中,您是否知道 Oracle 是否足够聪明以利用我的两个索引,或者这不可能,所以我应该坚持使用这两个 SELECT 吗?

谢谢!

4

2 回答 2

2

您可以使用 a UNION(或者UNION ALL如果您不想消除重复项)。

select ... from myTable where A = <something>
UNION [ALL]
select ... from myTable where B = <something>

或者,您可以将其与 OR 结合在一个查询中,如您所描述的,并查看查询计划以查看索引是否真的被排除在外。

Oracle 有一个非常聪明的优化器,使 SQL声明性的全部意义在于,您然后花时间告诉数据库您想要什么,并让数据库决定如何最好地获得它(必须说一个相当响亮的警告,因为在很多情况下你可以强制优化器做出错误的选择:但根据我的经验,你往往比其他数据库更晚地达到这个障碍)。

在您的情况下,Oracle 可能会做的是检查:

  • 存在哪些索引
  • 基数,即特定索引的不同值的“分布”
  • 统计数据,多少数据等。

然后做出明智的决定。并且该决定将基于执行查询时的当前数据(或至少是上次更新统计信息的时间)。因此可以使用提示来强制使用索引,但这样做可能会阻止 Oracle 在以后找到通过数据的最有效路径,此时数据看起来大不相同。

于 2012-10-05T09:00:20.260 回答
1

通常,尝试以强制 Oracle 使用索引的方式来设计您的 select 语句是一个坏主意,因为您不太可能确切地知道 Oracle 将如何实际使用优化器中的索引。

如果需要,您可以强制 Oracle 使用索引(带有提示),但优化器通常会做得更好。

于 2012-10-05T09:01:05.983 回答