【问题标题】:Oracle SQL use variable partition nameOracle SQL 使用可变分区名称
【发布时间】:2014-11-01 14:46:06
【问题描述】:

我运行一个每日报告,该报告必须查询另一个单独更新的表。由于源表中的大量记录(每天 8M+)每天都存储在它自己的分区中。分区的标准格式为P ... 4 digit year ... 2 digit month ... 2 digit date,所以昨天的分区是P20140907

目前我使用这个表达式,但必须每天手动更改分区名称:

select * from <source_table> partition (P20140907) where ....

通过使用sysdatetoCharConcat,我创建了另一个名为P_NAME2 的表,它将自动生成并更新一个字符串值作为我需要读取的分区的名称。现在我需要更新我的主查询,以便它这样做:

select * from <source_table> partition (<string from P_NAME2>) where ....

【问题讨论】:

    标签: sql oracle partition


    【解决方案1】:

    你工作太辛苦了。 Oracle 已经为您完成了所有这些事情。如果您使用正确的日期范围查询表,oracle 将仅在相关分区上执行操作 - 这称为 pruning

    我建议阅读docs

    如果您仍然持怀疑态度,请查询 all_tab_partitions.HIGH_VALUE 以获取每个分区的高价值(您创建的表...)。

    【讨论】:

    • 如果我尝试使用日期范围进行选择,则处理负载和运行时间要高得多,因为它仍会扫描整个数据库以查找日期限制。通过分区工作效率更高。源表已预先分区到 2030 年,未来日期为空。选择最高的分区不会找到任何东西。 (源表不是我的)
    • @CJC - haki 的查询显示每个分区允许的最大值,而不是最高分区。你的统计数据是最新的吗?您的 where 子句是否强制进行隐式数据转换,从而停止正确应用修剪/索引(例如,与字符串而不是日期进行比较)?
    【解决方案2】:

    我想我会回来分享我最终是如何解决这个问题的。源数据库有跨分区泄漏日期的习惯,这就是为什么一天的查询会超出单个分区的原因。我不能影响这个,只是解决它...

    begin    
    execute immediate 
    'create table LL_TEST as
    select *
    from SCHEMA.TABLE Partition(P'||TO_CHAR(sysdate,'YYYYMMDD')||')
    where COLUMN_A=''Something''
    and COLUMN_B=''Something Else''
    ';
    end
    ;
    

    使用 PL/SQL 脚本,我使用TO_CHAR(sysdate,'YYYYMMDD') 创建分区名称,并将其余的查询连接到它周围。

    请注意,您在 where 子句中搜索的值需要双撇号,以便将 'Something' 发送到脚本中您需要 ''Something'' 的查询。

    它可能不漂亮,但它适用于我必须使用的数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-03
      • 2016-06-21
      • 1970-01-01
      相关资源
      最近更新 更多