【问题标题】:Oracle index containing all columns of another index, right or wrongOracle 索引包含另一个索引的所有列,正确或错误
【发布时间】:2017-06-27 14:07:06
【问题描述】:

我正在开发一个Oracle 12c 数据库。 我有一张桌子被查询了很多。一个查询在 where 子句中使用列 A 和 B,另一个查询在 where 子句中使用 A、B、C、D 和 E 列。我想加快查询速度。

我添加了 2 个非唯一索引,一个在 A & B 上,一个在 A & B & C & D & E 上,所以我的第二个索引实际上包括第一个索引列。这是正确的吗?技术错误?还是视情况而定?

在这种情况下,在不同列上查询表时,索引的最佳做法是什么?索引有什么影响?

【问题讨论】:

    标签: database indexing query-optimization oracle12c database-tuning


    【解决方案1】:

    在这种情况下,不需要索引 (A,B),因为您有索引 (A,B,C,D,E)。查询可以有效地使用索引的前导部分。由于必须维护索引,因此索引将对 DML(索引、更新、删除)产生影响。

    话虽如此,优化器可能会选择不使用索引并执行全表扫描,因为它更便宜 - 这是正常、正确的行为。例如,如果我的表有 100 万行,而我的查询返回了其中的 50%,那么进行全表扫描可能会比使用索引更好。

    【讨论】:

    • 谢谢鲍勃。关于“...可以使用索引的前导部分”,如果我的第一个索引是 C、D 而不是 A、B 怎么办? ABCDE 指数是否也包括 C、D 指数?如果我还想要 C,D 索引,是否应该将其声明为单独的索引?
    • 如果您的索引在 (A,B,C,D,E) 上,而您在 C,D 上的位置,优化器可能使用索引跳过扫描操作.然而,众所周知,这些成本很难准确计算,而且通常表现不佳。在这种情况下,您可能只需要 (C,D) 上的索引。但是,不要发疯并开始索引每个组合,因为您最终会导致索引膨胀!
    • 哈哈 :) 谢谢 Bob,我绝对不会用冗余索引来破坏数据库,我正在谷歌搜索并详细研究优化解决方案以实现这一目标。
    • @MahdiTahsildari 小心“由 Google 调整”。那里有一些很好的信息;但也有很多完全的废话。在大多数情况下,Stack Overflow 是一个很好的资源,所以回来提出新问题 :)
    • 旁注。我正在考虑这种极端情况,其中 C、D 和 E 是“大”字段,您可能只想例如计算 AB 组合的出现次数。在这种情况下,AB 上的索引将被覆盖,并且由于它只包含两个“小”字段,因此它会导致比 ABCDE 少得多的 IO(因此可能会更好地缓存)。如果您需要(非常)经常这样做,则维护此“多余索引”的成本可能会被查询时减少 IO 的收益所抵消。与往常一样,事情在很大程度上取决于数据和用例......几乎没有一个适合所有情况的答案。
    猜你喜欢
    • 2017-10-04
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多