Oracle
 sql >> Database >  >> RDS >> Oracle

Parallel Hint all'interno di Dynamic SQL di Oracle viene eseguito in parallelo?

TLDR

Molto probabilmente hai dimenticato di abilitare il DML parallelo.

ALTER SESSION ENABLE PARALLEL DML;

Inoltre, se forzi esecuzione parallela di solito non usa suggerimenti paralleli e viceversa.

Impostazione di esempio (11.2)

create table TAB_HIST (
col1 int,
col2 int,
col3 varchar2(4000))
PARTITION BY RANGE (col1) 
interval(1000000)
(
  partition p_init values less than (1000000) 
); 


create table TAB_SRC (
col1 int,
col2 int,
col3 varchar2(4000)
)
PARTITION BY RANGE (col1) 
interval(1000000)
(
  partition p_init values less than (1000000) 
);

insert into tab_src
select rownum, rownum,  rpad('x',1000,'y') from dual connect by level <= 100000;
commit;

Inserisci

Devi abilita DML parallelo nel primo passaggio

ALTER SESSION ENABLE PARALLEL DML;

Si noti che in alternativa è possibile utilizzare un suggerimento

INSERT /*+ ENABLE_PARALLEL_DML */ …

Inoltre, se forzi DML e QUERY paralleli, in genere non usi suggerimenti paralleli . Sto suggerendo un inserimento diretto con APPEND che viene spesso utilizzato in questa situazione.

DECLARE
v_parallel_degree NUMBER := 2;
BEGIN
    EXECUTE IMMEDIATE 'ALTER SESSION FORCE PARALLEL DML PARALLEL ' || v_parallel_degree;
    EXECUTE IMMEDIATE 'ALTER SESSION FORCE PARALLEL QUERY PARALLEL ' || v_parallel_degree;

    EXECUTE IMMEDIATE 'INSERT /*+ APPEND */ INTO TAB_HIST  
                SELECT  *
                FROM  TAB_SRC PARTITION(P_INIT)';
END;
/

Come verificare se la tabella è stata inserita in parallelo? Il modo più semplice è interrogare la tabella (prima di eseguire un commit):se viene visualizzato l'errore sottostante, è un inserimento diretto parallelo.

select count(*) from TAB_HIST;
ORA-12838: cannot read/modify an object after modifying it in parallel

Indice

Se specifichi una laurea parallela in create index dichiarazione che non è necessario attivare o forzare qualsiasi cosa.

DECLARE
v_parallel_degree NUMBER := 2;
BEGIN
    
    EXECUTE IMMEDIATE 'CREATE UNIQUE INDEX idx_pk ON TAB_HIST
                 (COL1,COL2,COL3)
                 LOCAL
                 NOLOGGING PARALLEL ' || v_parallel_degree;
END;
/

Il controllo è semplice come cercare la laurea nel dizionario dati

select DEGREE from user_indexes where table_name = 'TAB_HIST';

DEGREE 
--------- 
2

Nota che dopo aver creato l'indice in modalità parallela, spesso vuoi reimpostare il DOP su uno. In caso contrario, alcune semplici query di loop nidificate potrebbero essere confuse e apriranno una query parallela...