当table是散列分区时查询确切的分区

Query the exact partition when table is hash-partitioned

当我想查询单个分区时,我通常使用类似的东西:

Select * from t (partition p1)

但是当你必须在你的 pl/sql 代码中查询它时,它会使用 execute immediate 和语句的硬解析。

好的,对于 RANGE 分区 table(让它成为 date 类型的 SOME_DATE)我可以像

那样解决它
Select * from t where some_date <= :1 and some_date > :2

假设 :1:2 代表分割键。

好吧,对于 LIST 分区 table 我可以轻松地指定分区键字段的确切值,例如

Select * from t where part_key = 'X'

那么 HASH 分区呢?例如,我有一个 table 被 hash(id) 划分为 16 个分区。我有 16 个作业,每个作业都处理自己的分区。所以我必须那样使用它

Select * from t (partition p<n>)

问题是:我可以像这样吗

Select * from t where hash(id) = :1

要强制分区修剪取整个第 n 个分区?

当你只有 16 个分区时没关系,但在我的例子中我有复合分区(日期 + 哈希(id)),所以每次作业处理一个分区它总是一个新的 sql_id 并且它结束了共享池快速增长

似乎 Oracle internally uses the ora_hash function(至少从 10g 开始)为分区赋值。因此,您可以使用它来读取单个分区中的所有数据。不幸的是,因为你会 运行 像

这样的查询
select *
  from t
 where ora_hash( id, 9 ) = 6

为了获取 8 个散列分区中第 6 个中的所有数据,我希望 Oracle 必须读取 table 中的每个分区(并计算每个 id 的散列),因为优化器不会足够聪明,无法识别您的表达式恰好恰好映射到其内部分区策略。所以我认为您不希望这样做来拆分数据以供不同线程处理。

根据这些线程在做什么,是否可以改用 Oracle 的内置并行性(如果您正在进行 ETL 处理,可能会合并可并行化的流水线 table 函数)。如果您告诉 Oracle 使用 16 个并行线程并且您的 table 有 16 个分区,Oracle 几乎肯定会在内部做正确的事情。