2010-03-11 116 views
0

有人可以提供一個如何在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

回答

2

有一個很好的報告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; 
/