2013-11-21 10 views
5

ho preparato alcuni fiddle:Oracle 11gR2: Posso utilizzare DBMS_PARALLEL_EXECUTE per eseguire il mio codice PL/SQL personalizzato?

CREATE TABLE t_process 
    ("process_number" int, "process_status" varchar2(12)) 
; 

INSERT ALL 
    INTO t_process ("process_number", "process_status") 
     VALUES (1, 'PROCESSING') 
    INTO t_process ("process_number", "process_status") 
     VALUES (2, 'PROCESSING') 
    INTO t_process ("process_number", "process_status") 
     VALUES (3, 'TO_BE_KILLED') 
    INTO t_process ("process_number", "process_status") 
     VALUES (4, 'PROCESSING') 
    INTO t_process ("process_number", "process_status") 
     VALUES (5, 'PROCESSING') 
    INTO t_process ("process_number", "process_status") 
     VALUES (6, 'TO_BE_KILLED') 
    INTO t_process ("process_number", "process_status") 
     VALUES (7, 'TO_BE_KILLED') 
    INTO t_process ("process_number", "process_status") 
     VALUES (8, 'WAITING') 
    INTO t_process ("process_number", "process_status") 
     VALUES (9, 'KILLED') 
SELECT * FROM dual 
; 

Questo è il mio regime di perfezionamento:

CREATE OR REPLACE PROCEDURE MY_PROCEDURE(IN_ID IN NUMBER) IS 
BEGIN 
    UPDATE T_PROCESS SET process_status = 'KILLING' WHERE process_number = IN_ID; 
    COMMIT; 
    -- DO SOME STUFF 
    UPDATE T_PROCESS SET process_status = 'KILLED' WHERE process_number = IN_ID; 
    COMMIT; 
END MY_PROCEDURE; 

Ora voglio usare DBMS_PARALLEL_EXECUTE per eseguire questa usanza SQL:

DECLARE 
    id1 number = :id1; 
    id2 number = :id2; 
BEGIN 
    MY_PROCEDURE(id1); 
END; 

Quindi, la mia domanda è:

Posso utilizzare DBMS_PARALLEL_EXECUTE per eseguire la dichiarazione SQL sopra?

perché ho trovato solo UPDATE esempi. Forse CREATE_CHUNKS_BY_SQL per selezionare solo TO_BE_KILLED e poi RUN_TASK con dichiarazione di cui sopra?

risposta

3

SI, Si può benissimo fare 11g in poi. Sono sorpreso perché non è stato suggerito qui.

è possibile eseguire una procedura interna run_task come begin MY_PROCEDURE(:start_id, :end_id); end;

Potrebbe essere necessario modificare procedimento per accettare due parametri: START_ID,: end_id

Ecco il codice di esempio (sulla base di ‘create_chunks_by_rowid’).

DECLARE 
    l_task  VARCHAR2(30) := 'parallel_processing'; 
    l_sql_stmt VARCHAR2(32767); 
    l_try  NUMBER; 
    l_status NUMBER; 
BEGIN 
    DBMS_PARALLEL_EXECUTE.create_task (task_name => l_task); 

    DBMS_PARALLEL_EXECUTE.create_chunks_by_rowid(task_name => l_task, 
               table_owner => 'SCHEMANAME', 
               table_name => 'T_PROCESS', 
               by_row  => TRUE, 
               chunk_size => 10000); 

    l_sql_stmt := 'begin MY_PROCEDURE(:start_id, :end_id); end;'; 

    DBMS_PARALLEL_EXECUTE.run_task(task_name  => l_task, 
           sql_stmt  => l_sql_stmt, 
           language_flag => DBMS_SQL.NATIVE, 
           parallel_level => 10); 

    -- If there is error, RESUME it for at most 2 times. 
    l_try := 0; 
    l_status := DBMS_PARALLEL_EXECUTE.task_status(l_task); 
    WHILE(l_try < 2 and l_status != DBMS_PARALLEL_EXECUTE.FINISHED) 
    Loop 
    l_try := l_try + 1; 
    DBMS_PARALLEL_EXECUTE.resume_task(l_task); 
    l_status := DBMS_PARALLEL_EXECUTE.task_status(l_task); 
    END LOOP; 

    DBMS_PARALLEL_EXECUTE.drop_task(l_task); 
END; 
/

È possibile create chunks seguendo i mezzi e in base alla propria situazione/comfort.

CREATE_CHUNKS_BY_NUMBER_COL - Se si desidera aggiornare da 'process_number'

CREATE_CHUNKS_BY_SQL - Se si pensa BY_SQL sta per darvi un insieme molto più piccolo di pezzi da lavorare. Attenti al fatto che ogni blocco sarà in grado di elaborare solo 1 riga per blocco (start_id e end_id lo stesso per ogni blocco) in questo approccio.

+0

Un altro punto, uno non ha bisogno di impegnarsi all'interno della propria procedura personalizzata come DBMS_PARALLEL_EXECUTE.run_task lo farà automaticamente !! – pahariayogi

3

No (o almeno non senza reali hack sporco). Se si desidera eseguire PL/SQL in parallelo, ho appreso le seguenti opzioni:

  1. Utilizzare dbms_job. L'hai già pagato con la licenza, molti DBA-s lo capiscono e funziona in modo ragionevole se non hai requisiti di regolamentazione, controllo, sicurezza o manutenzione troppo elevati. Devi costruirlo tu stesso. È stato intorno dal 1995 o giù di lì.
  2. Uso Cronacle di Redwood. Era il mio primo lavoro 20 anni fa, dolci ricordi. Permette di eseguire facilmente i lavori su un cluster su Oracle usando la sintassi simile a Oracle ed è più affidabile di dbms_job, ha una registrazione e un'esecuzione migliori delle istruzioni del sistema operativo, oltre alla stampa. Ma ti costa denaro.
  3. Usa Invantive Scheduler. Lavoro lì al momento ed è simile a Cronacle, ma mirato ai sistemi amministrativi. E odio programmare lavori complessi quando non ho un facile accesso al sistema operativo, ai file e soprattutto alla registrazione di dbms_output e così via.
  4. Utilizzare lo schedulatore specifico dell'applicazione. Ad esempio, la suite Oracle E-business è dotata di un buon programmatore con sicurezza, esclusioni reciproche, registrazione ragionevole, ecc. Se si dispone già di un pacchetto di questo tipo, l'uso è normalmente gratuito e l'amministratore dell'applicazione ha esperienza con esso.

Quando sei un programmatore e non c'è ancora uno standard e non c'è bisogno di più elaborazione parallela, potresti andare su dbms_job. Quando il volume aumenta o quando ci sono più requisiti funzionali, scegli una soluzione migliore.