sql - 对表进行哈希分区时查询确切的分区
问题描述
当我想查询单个分区时,我通常使用类似的东西:
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
,它最终会快速共享池增长
解决方案
看来Oracle 在内部使用该ora_hash
函数(至少从 10g 开始)为分区分配值。因此,您可以使用它从单个分区中读取所有数据。不幸的是,因为你会运行一个像这样的查询
select *
from t
where ora_hash( id, 9 ) = 6
要获取 8 个哈希分区中的第 6 个中的所有数据,我希望 Oracle 必须读取表中的每个分区(并计算每个分区上的哈希id
),因为优化器不会足够聪明,无法识别您的表达式恰好映射到其内部分区策略。所以我认为你不想这样做来分割数据以供不同的线程处理。
根据这些线程在做什么,是否可以改用 Oracle 的内置并行性(如果您正在执行 ETL 处理,可能会合并诸如可并行化的流水线表函数之类的东西)。如果您告诉 Oracle 使用 16 个并行线程并且您的表有 16 个分区,那么 Oracle 在内部几乎肯定会做正确的事情。
推荐阅读
- xamarin - 如何使用 xamarin 表单中的列表调用动态数据
- spring-boot - Thymeleaf 将预处理字符串解析为日期并格式化
- apache-kafka - Kafka 删除日志段,即使它配置为无限保留
- openstack - 查找 OpenStack 资源的 value_specs 支持的内容
- angular5 - Angular 5 ngFor let i=index+3
- javascript - 如何阻止所有离子 ngfor 按钮一次被点击
- javascript - NodeJs Express Session Management
- grafana - Grafana 的面板特定注释或类似机制
- input - 如何在运行前获取 Kubernetes 中的 Pod 输入数据大小?
- swift - DispatchGroup().wait() 之后的代码从未调用过