【问题标题】:Convincing the Oracle SQL optimizer that an indexed (though non-UNIQUE) column actually contains unique values in practice使 Oracle SQL 优化器相信索引列(尽管非唯一)实际上包含唯一值
【发布时间】:2012-10-06 11:41:42
【问题描述】:

我正在编写一个使用非UNIQUE 索引列的视图。但是,在我看来,我相信该列将仅包含唯一值(由于 WHERE 子句中施加的条件)。

真正的问题发生在有人根据该列查询视图时(例如SELECT * FROM MY_VIEW WHERE COLUMN_WITH_NON_UNIQUE_INDEX = 'foo')。优化器确信它将接收 许多 行(因为从技术上讲,索引不是UNIQUE)。因此,优化器避免在视图中的其他位置使用其他索引,以支持全表扫描(不酷)。

有没有办法让优化器相信具有非UNIQUE 索引的列实际上将包含唯一值?当然,重复值可能会潜入列中,但它会被视为错误,不应导致合法的唯一数据受到影响。

不幸的是,我无法控制有问题的桌子(叹气)。

【问题讨论】:

  • 你的统计数据是最新的吗?它应该已经在使用适当的索引,如果它们确实是有利的。
  • 唯一索引/唯一约束告诉优化器你想告诉它什么。为什么您会期望还有另一种方法可以做到这一点?
  • @Mat:统计数据过时了,所以我在桌子上收集了统计数据。它改进了解释计划的某些部分,但不是这个特定部分。我会继续调查。
  • @Dems:在看到优化器可用的所有提示后,我怀疑可能有某些东西可以建议此信息。
  • 如果您想强制执行,请尝试使用普通的 /*+ 索引 (...) */ 提示并 测量实际查询时间(不仅仅是解释计划) .

标签: sql oracle optimizer-hints cost-based-optimizer


【解决方案1】:

您可以尝试以下方法:

使用 dbms_stats 将 METHOD_OPT 设置为 FOR ALL COLUMNS SIZE AUTO 收集有关表的统计信息 使用此设置,Oracle 会自动确定哪些列需要直方图以及每个直方图的桶数(大小)。您还可以手动指定哪些列应该有直方图以及每个直方图的大小。

dbms_stats.gather_table_stats(
ownname => 'schemaname' ,
tabname => 'tablename' ,
estimate_percent => 100 ,
method_opt => 'for all indexed columns size auto' ,
 cascade => true);

【讨论】:

    【解决方案2】:

    Oracle 允许您在视图上创建唯一(和主键)约束,这些约束未强制执行,但为优化器提供了此类信息

    ALTER VIEW your_view_name
      ADD CONSTRAINT name_of_constraint UNIQUE( column_with_non_unique_index )
      RELY DISABLE NOVALIDATE;
    

    这将告诉 Oracle,它可以依赖数据是唯一的这一事实,但它不需要验证约束。然而,优化器将能够使用约束提供的额外元数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-08
      • 2011-11-23
      相关资源
      最近更新 更多