流水线功能

问题描述:

有人可以提供一个如何在oracle pl/sql中使用并行表功能的例子。我们需要运行15年的大量查询并将结果合并。流水线功能

SELECT * 
    FROM Table(TableFunction(cursor(SELECT * FROM year_table))) 

...是我们想要的有效。最内层的选择会提供所有年份,而表函数将每年执行一次并运行大量查询并返回一个集合。我们现在面临的问题是,所有年份都被提供给一个表函数本身,我们宁愿每年都平行调用表函数。我们尝试通过散列和范围进行各种分区,但没有任何帮助。

另外,我们可以从函数声明中删除关键字PIPELINED吗?因为我们没有执行任何转换,只需要结果集合。

+1

你能描述一下你想什么,以及为什么你认为你需要一个管道功能?目前,这听起来像你需要每年运行一个查询。 – 2010-03-11 15:55:46

+0

即使我们每年运行一个查询,我们也需要在所有年份范围内并行进行。如果有比使用并行流水线更好的选项,请建议。 – Prakash 2010-03-15 09:28:06

有一个很好的报告here

有替代方法(即通过YEAR_TABLE游标并提交DBMS_JOB每年每个“一年来的工作”来处理会插入其结果到一个表如“主”的工作。

一旦所有产生的作业你只需要从表中得到结果

PS。我怀疑并行流水线将不会做你想做的事 我创建了一个只有三个特定值的大表 然后我创建了一个并行流水线函数,它只是推出了正在执行的进程的SID(见下文)以及它所处理的行数 我有一个SQL挑出这三行,并将其作为光标传递给函数。 大部分功能推出了两个不同的SID(这是解释计划告诉我它选择的平行度)。有时它显示两个进程已经执行,但所有三个行都由这些进程中的一个进程处理。

所以并非如此,行将被从光标中选出并传递给并行从机进行处理,而是每个并行进程将被分配一张驱动表来处理。随着一张小桌子,它可能不会考虑并行即使它没有,它可能只是分配第50行到第一个进程等

CREATE OR REPLACE FUNCTION test_pp(p_source  IN SYS_REFCURSOR) 
    RETURN TAB_CHAR_4000 PIPELINED 
    PARALLEL_ENABLE (PARTITION p_source BY ANY) 
IS 
    v_num NUMBER; 
BEGIN 
    FETCH p_source INTO v_num; 
    WHILE p_source%FOUND LOOP 
      PIPE ROW(sys_context('USERENV','SID')); 
      FETCH p_source INTO v_num; 
    END LOOP; 
    PIPE ROW(sys_context('USERENV','SID')||':'||p_source%ROWCOUNT); 
    CLOSE p_source; 
    RETURN; 
END test_pp; 
/