当表进行哈希分区时,查询确切的分区



当我想查询单个分区时,我通常会使用这样的东西:

Select * from t (partition p1)

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

好的,对于RANGE分区表(让它是date类型的SOME_DATE(,我可以像一样解决它

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

假设CCD_ 3和CCD_。

好吧,对于LIST分区表,我可以很容易地指定分区键字段的确切值,比如

Select * from t where part_key = 'X'

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

Select * from t (partition p<n>)

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

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

要强制分区修剪,需要整个第n个分区吗?

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

Oracle内部似乎使用ora_hash函数(至少从10g开始(为分区分配值。因此,您可以使用它从单个分区读取所有数据。但不幸的是,由于您将运行类似的查询

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

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

根据这些线程所做的工作,是否可以使用Oracle内置的并行性(如果您正在进行ETL处理,则可能包含可并行的流水线表函数(。如果您告诉Oracle使用16个并行线程,并且您的表有16个分区,那么Oracle内部几乎肯定会做正确的事情。

最新更新