首页 > 解决方案 > 对表进行哈希分区时查询确切的分区

问题描述

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

Select * from t (partition p1)

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

好的,对于 RANGE 分区表(让它成为 SOME_DATEdate类型),我可以像这样解决它

Select * from t where some_date <= :1 and some_date > :2

假设:1:2代表分区债券。

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

Select * from t where part_key = 'X'

那么哈希分区呢?例如,我有一个按hash(id)16 个分区划分的表。我有 16 个工作,每个工作都处理自己的分区。所以我必须这样使用它

Select * from t (partition p<n>)

问题是:例如,我可以这样做吗

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

要执行分区修剪,需要整个第 n 个分区?

当你只有 16 个分区时没关系,但在我的情况下,我有复合分区(日期 + 哈希(id)),所以每次作业处理一个分区它总是一个新的sql_id,它最终会快速共享池增长

标签: sqloracleoracle11gpartitioningdatabase-partitioning

解决方案


看来Oracle 在内部使用该ora_hash函数(至少从 10g 开始)为分区分配值。因此,您可以使用它从单个分区中读取所有数据。不幸的是,因为你会运行一个像这样的查询

select *
  from t
 where ora_hash( id, 9 ) = 6

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

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


推荐阅读