【问题标题】:SQL/Oracle: SELECT with OR on table with two indicesSQL/Oracle:在具有两个索引的表上使用 OR 选择
【发布时间】:2012-10-05 08:55:41
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

    标签: sql oracle indices


    【解决方案1】:

    您可以使用UNION(如果您不想消除重复,则可以使用UNION ALL)。

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

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

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

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

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

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

    【讨论】:

    • 是的,我认为这就是他在第二段中的意思(即 UNION)......
    • 所以我是否正确地从您的回复中假设我应该坚持使用 OR 版本(即一个 SELECT)并让 Oracle 完成其余的工作?
    • 是的,首先。编写声明式 SQL,查看 oracle 使用什么计划,(重新)索引等。但不要试图欺骗优化器!
    【解决方案2】:

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

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

    【讨论】:

    • 抱歉,但我不明白这与我的问题有何关系——Oracle 是否知道我在一个 SELECT 中的两个索引,还是我需要使用两个 SELECT?
    • 仅仅因为您已经在相关列上建立了索引,这并不能保证 Oracle 会使用它们。这取决于查询、数据量、统计数据和许多其他因素。如果您想查看某个索引是否在给定时间点使用,则需要运行 EXPLAIN PLAN。
    • 好的,那么您是否建议将一个 SELECT 与 OR 一起使用,让 Oracle 完成其余的工作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 2016-08-03
    • 2022-11-23
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多