当我要查询单个分区时,我通常使用类似的东西:
Select * from t (partition p1)
但是当您必须在pl / sql代码中查询它时,它涉及到使用execute immediate
并对该语句进行硬解析。
好的,对于RANGE分区表(让它是date
类型的SOME_DATE),我可以像这样解决它
Select * from t where some_date <= :1 and some_date > :2
假设:1
和:2
代表分区键。
好吧,对于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个分区是可以的,但就我而言,我有复合分区(date + hash(id)),因此每次作业处理一个分区时,它总是一个新的sql_id
,并且很快就会结束共享池增长
答案 0 :(得分:2)
似乎Oracle internally uses the ora_hash
function(至少从10g起)将值分配给分区。因此,您可以使用它从单个分区读取所有数据。不过遗憾的是,由于您将要运行类似
select *
from t
where ora_hash( id, 9 ) = 6
要获取8个散列分区中第6个的所有数据,我希望Oracle必须读取表中的每个分区(并在每个id
上计算散列),因为优化程序没有用聪明到足以识别出您的表达式恰好映射到其内部分区策略。因此,我认为您不想这样做将数据拆分成不同的线程进行处理。
根据这些线程在做什么,有可能改而使用Oracle的内置并行性(如果正在执行ETL处理,则可能合并诸如可并行化的流水线表函数之类的东西)。如果您告诉Oracle使用16个并行线程,并且您的表具有16个分区,那么Oracle几乎肯定会在内部做正确的事。