【问题标题】:Force partition pruning on Oracle在 Oracle 上强制分区修剪
【发布时间】:2017-11-01 06:18:07
【问题描述】:

我有一个类似的查询

select *
from small_table A
inner join huge_table B on A.DATE =B.DATE

huge_table是按DATE分区的,PK是DATE、some_id和some_other_id(所以join not是通过pk index来完成的)。 small_table 只包含几个日期。

SQL 总耗时 48 分钟

由于某种原因,解释计划给了我一个“PARTITION RANGE (ALL)”,其基数很高。看起来像访问整个表,而不仅仅是 small_table.DATE 指示的分区

如果我将 SQL 放入循环中并执行

for o in (select date from small_table)
loop
    select *
    from small_table A
    inner join huge_table B on A.DATE =B.DATE
    where B.DATE=O.DATE
end loop;

只需 2 分 40 秒(完整循环)。 有什么方法可以强制在 Oracle 12c 上进行分区修剪?

附加信息:

small_table 有 13 个不同日期的 37 条记录。 huge_table 拥有 80 亿条记录,包含 179 个日期/分区。 SQL 需要来自small_table 的一个字段,但我可以调整 SQL 使其不使用它

更新:

使用use_nl hint,现在执行计划中的基数显示更准确,执行时间从48分钟缩短到4分钟。

select /* use_nl(B) */*
from small_table A
inner join huge_table B on A.DATE =B.DATE

【问题讨论】:

  • small_table 具有可变数量的注册表。在每次执行时被截断并填充。
  • 抱歉,我在编辑之前的评论时遇到了问题。 small_table 有 13 个不同日期的 37 个注册表。huge_table 有 800 万个注册表,有 179 个日期/分区。关于统计。我怎样才能得到它?
  • 是的,来自 user_tables 的统计数据是正确的,有 37 个注册表。 SQL 需要 small_table 中的一个字段,但我可以调整 SQL 使其不使用。
  • 抱歉无法进行聊天。

标签: oracle performance optimization partitioning oracle12c


【解决方案1】:

这似乎是个问题:

"small_table 有 13 个不同日期的 37 个注册表。huge_table 有 800 万个注册表,有 179 个日期/分区...。 SQL 需要来自small_table 的一个字段,但我可以调整 SQL 使其不使用它“

根据您发布的 SQL,您将仅在两个表的 DATE 列上加入这两个表,而没有其他条件。如果确实如此,您正在生成一个交叉连接,其中huge_table 的每个分区都连接到small_table 2-3 次。因此,您的结果集可能比您预期的要大得多,这意味着更多的数据库工作,这意味着更多的时间。

另外需要注意的是small_table到huge_table分区的基数大约是1:4;优化器并不知道实际上只有 13 个不同的 huge_table 分区在起作用。

优化应该是一门科学,这比任何事情都要猜测,但试试这个:

select B.*
from ( select /*+ cardinality(t 13) */
             distinct t.date
        from small_table t ) A
inner join huge_table B 
    on A.DATE =B.DATE

这应该通知优化器只需要一小部分huge_table 分区,这可能使其选择分区修剪。它还删除了笛卡尔积,这也应该提高性能。显然,您需要应用您提到的调整,以消除从small_table 查询其他任何内容的需要。

【讨论】:

  • 谢谢,最后一个小的变化可以解决问题。使用 /* use_nl(B)*/ 强制执行“PARTITION RANGE (ITERATOR)”。现在结果接近循环了。
猜你喜欢
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
  • 2011-03-18
  • 2011-01-18
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多