Oracle
 sql >> Base de données >  >> RDS >> Oracle

Parallel Hint dans Dynamic SQL d'Oracle s'exécute-t-il en parallèle ?

TLDR

Vous avez probablement oublié d'activer le DML parallèle.

ALTER SESSION ENABLE PARALLEL DML;

De plus, si vous forcez l'exécution parallèle que vous ne faites généralement pas utiliser des conseils parallèles et vice versa.

Exemple de configuration (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;

Insérer

Vous devez activer DML parallèle dans la première étape

ALTER SESSION ENABLE PARALLEL DML;

Notez qu'en alternative, un indice peut être utilisé

INSERT /*+ ENABLE_PARALLEL_DML */ …

De plus, si vous forcez parallèle DML et QUERY, vous n'utilisez généralement pas les indications parallèles . Je suggère une insertion directe avec APPEND qui est souvent utilisé dans cette situation.

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;
/

Comment vérifier si la table a été insérée en parallèle ? Le moyen le plus simple est d'interroger la table (avant de faire un commit) - si vous obtenez l'erreur ci-dessous, il s'agit d'une insertion directe parallèle.

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

Index

Si vous spécifiez un degré parallèle dans le create index déclaration que vous n'avez pas besoin d'activer ou forcer n'importe quoi.

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;
/

La vérification est aussi simple que de regarder le diplôme dans le dictionnaire de données

select DEGREE from user_indexes where table_name = 'TAB_HIST';

DEGREE 
--------- 
2

Notez qu'après avoir créé un index en mode parallèle, vous souhaitez souvent réinitialiser le DOP à un. Sinon, certaines requêtes simples en boucle imbriquée peuvent être confuses et ouvriront une requête parallèle...