【问题标题】:Best Index For Partitioned Table分区表的最佳索引
【发布时间】:2014-05-13 05:32:01
【问题描述】:

我正在查询一个相当大的表,该表已按日期(由其他人)每天划分到一个分区中。平均每天大约有 250,000 条记录。经常查询将按天的范围进行——通常查找一天、一周 7 天或一个日历月。现在查询超过 2 周的性能不佳——创建了一个正常的日期索引。如果我查询超过 5 天,它不使用索引,如果我使用索引提示,它执行正常。从大约 5 天到 14 天,但除此之外,索引提示没有多大帮助。

鉴于提示比优化器做得更好,我正在收集表上的统计信息。

但是,我接下来的问题是,一般来说,如果我想在表中的日期字段上创建索引,是否最好创建范围分区索引?是否最好创建一个每日范围类似于表分区的范围索引?最好的策略是什么?

这是 Oracle 11g。

谢谢,

【问题讨论】:

    标签: sql oracle indexing partitioning


    【解决方案1】:

    与您的问题相关,分区策略将取决于您将如何查询数据,最好的策略是查询尽可能少的分区。例如如果您要运行每月报告,您宁愿创建每月范围分区而不是每日范围分区。如果您的所有查询都围绕几天内的数据,那么每日范围分区就可以了。

    鉴于您在我的意见中提供的数字,您过度划分数据。

    附言查询每个分区需要额外的读取(如果它只是一个分区),所以优化器选择全表访问以减少索引的读取。

    【讨论】:

    • 使用索引提示的成本是不使用它的 5 倍,但使用索引提示查询运行速度快 20 倍。这正常吗?
    • 这很正常,正如我所说,当您使用分区时会导致额外的读数,因为索引结构与您没有分区的结构不同。当您只查询少数分区时,oracle 将使用分区修剪,您很好。您必须阅读文档并阅读全局索引和本地索引之间的区别,如果您交换/删除/..(这些操作使全局索引无效)分区很少您可以将索引重新创建为全局索引,它应该有助于查询数据
    【解决方案2】:

    尝试在日期列上创建全局索引。如果索引已分区并且您选择 - 比如说 - 14 天,那么 Oracle 必须读取 14 个索引。在整个表上有一个索引,即“全局索引”,它必须只读取 1 个索引。

    注意,当你截断或删除一个分区时,你必须在之后重建索引。

    【讨论】:

    • 我最初创建的索引没有任何选项——所以默认情况下这是一个全局非分区索引,对吗?
    • 这就是我在帖子中的意思,在添加了有关全局索引的评论后,我已经阅读了您的帖子
    【解决方案3】:

    猜测您可能写错了 SQL。

    您说您是按日期查询。如果您的日期列有时间部分,并且您想从一天中的特定时间提取记录,例如20:00-21:00,那么是的,索引会是有益的,我会为此推荐一个本地索引(按天分区,就像表格一样)。

    但是由于您的查询跨越了几天,看来情况并非如此,您只需要所有数据(可能被其他一些属性过滤)。如果是这样,分区完全扫描总是比索引访问快得多...前提是您从分区修剪中受益!因为如果不是 - 而且您实际上是在执行全表扫描 - 这预计会非常非常慢(在大多数情况下)。

    那么会出什么问题呢?您是否在 WHERE 子句中使用纯日期?请注意:

    SELECT * FROM trx WHERE trx_date = to_date('2014-04-03', 'YYYY-MM-DD');
    

    将只扫描一个分区,而:

    SELECT * FROM trx WHERE trunc(trx_date) = to_date('2014-04-03', 'YYYY-MM-DD');
    

    将扫描所有分区,因为您将函数应用于分区键并且优化器无法再确定要扫描的分区。

    如果您提供了表定义、分区总数、示例数据和带有解释计划的查询,则更容易确定。如果可能,请编辑您的问题并提供更多详细信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-03
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      • 2017-05-29
      相关资源
      最近更新 更多