Oracle SQL 自动并行假脱机

Posted

技术标签:

【中文标题】Oracle SQL 自动并行假脱机【英文标题】:Oracle SQL parallel spooling automatically 【发布时间】:2013-08-05 11:51:18 【问题描述】:

我有一个繁重的查询,它将数据假脱机到发送给用户的 csv 文件中。我已经手动创建了并行会话,并正在使用过滤条件执行查询,以便我可以将最后的所有假脱机文件合并到一个文件中,从而减少生成数据的时间(通常需要大约 10 个小时,并行会话需要2.5-3 小时)。

我的问题是如何自动执行此操作,以便脚本找出 max(agreementid),然后将其分配到 X 个假脱机调用中,以生成 X 个文件,其中每个文件最多有 100000 条记录。

补充说明:我想我的问题不是很清楚。我会再解释一遍。

    我有一个包含大量数据的表/视图。 我需要将此数据假脱机到 CSV 文件中。 假脱机 CSV 文件需要大量时间。 我通过执行以下操作来运行并行线轴。 a) 选择 .... from ... 其中协议 ID 介于 1 到 1000000 之间; b) 选择 .... from ... 其中协议 ID 介于 1000001 到 2000000 之间; 依此类推,然后在多个会话中单独假脱机。 这有助于我生成多个文件,然后我可以将它们拼接在一起并与用户共享。 我需要一个脚本(我猜是基于 dos 或基于 AIX),它会从我的表中找到协议 ID 的最小值和最大值,并自动创建假脱机脚本并通过单独的 sql 会话执行它们,以便我自动生成文件.

不确定我是否可以让自己足够清楚。 感谢大家回复我之前的问题,但那不是我要查看的内容。

【问题讨论】:

【参考方案1】:

有点不清楚你想要什么,但我认为你想要一个查询来为 x 组 id(桶)找到一个低/高范围的协议 ID。如果是这样,请尝试类似(在此示例中使用 4 个存储桶):

select bucket, min(agreement_id), max(agreement_id), count(1)
from (
  select agreement_id, ntile(4) over (order by agreement_id) bucket
  from my_table
)
group by bucket;

编辑:如果您的问题在于假脱机多个查询和组合,我宁愿选择创建单个物化视图(在驱动表上的基础查询中使用并行)并刷新(完成,atomic_refresh=>false)需要的时候。刷新后,只需从快照表中提取(到 csv 或您想要的任何格式)。

【讨论】:

【参考方案2】:

可能有一种更简单的方法,但这会生成四个 ID 的“桶”,您可以将最小值和最大值插入参数化过滤条件:

select bucket, min(agreementid) as min_id, max(agreementid) as max_id
from (
    select agreementid,
        case when rn between 1 and cn / 4 then 1
            when rn between (cn / 4) - 1 and 2 * (cn / 4) then 2
            when rn between (2 * cn / 4) - 1 and 3 * (cn / 4) then 3
            when rn between (3 * cn / 4) - 1 and cn then 4
        end as bucket
    from (
        select agreementid, rank() over (order by agreementid) as rn,
            count(*) over () as cn from agreements
    )
)
group by bucket;

如果您想要每个存储桶的上限而不是固定数量的存储桶,那么您可以这样做:

select floor(rn / 100000), min(agreementid) as min_id, max(service_num) as max_id
from (
    select agreementid, rank() over (order by agreementid) as rn
    from agreements
)
group by floor(rn / 100000);

然后将每个最小值/最大值传递给 SQL 脚本,例如来自调用 SQL*Plus 的 shell 脚本。桶号也可以通过位置参数传递并用作假脱机文件名的一部分。

不过,我很好奇您确定的瓶颈是什么;您是否尝试过在数据库中将其作为并行查询运行,并带有 /*+ PARALLEL */ 提示?

【讨论】:

谢谢,我会尝试这两种方法。

以上是关于Oracle SQL 自动并行假脱机的主要内容,如果未能解决你的问题,请参考以下文章

假脱机多个文件

ORACLE 如何使用具有动态假脱机位置的假脱机

在没有假脱机或 utl_file 的 PL/SQL 中写入文件

无法在 oracle 中假脱机行大小 > 32676 的 clob 列

Oracle PL/SQL 中的字符编码问题

在 Oracle 的同一个假脱机中生成输出