流水线功能
问题描述:
有人可以提供一个如何在oracle pl/sql中使用并行表功能的例子。我们需要运行15年的大量查询并将结果合并。流水线功能
SELECT *
FROM Table(TableFunction(cursor(SELECT * FROM year_table)))
...是我们想要的有效。最内层的选择会提供所有年份,而表函数将每年执行一次并运行大量查询并返回一个集合。我们现在面临的问题是,所有年份都被提供给一个表函数本身,我们宁愿每年都平行调用表函数。我们尝试通过散列和范围进行各种分区,但没有任何帮助。
另外,我们可以从函数声明中删除关键字PIPELINED吗?因为我们没有执行任何转换,只需要结果集合。
答
有一个很好的报告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;
/
你能描述一下你想什么,以及为什么你认为你需要一个管道功能?目前,这听起来像你需要每年运行一个查询。 – 2010-03-11 15:55:46
即使我们每年运行一个查询,我们也需要在所有年份范围内并行进行。如果有比使用并行流水线更好的选项,请建议。 – Prakash 2010-03-15 09:28:06