sql >> データベース >  >> RDS >> Oracle

Oracleの動的SQL内の並列ヒントは並列で実行されますか?

    TLDR

    おそらく、並列DMLを有効にするのを忘れたでしょう。

    ALTER SESSION ENABLE PARALLEL DML;
    

    さらに、強制した場合 通常しない並列実行 並列のヒントを使用する 逆もまた同様です。

    サンプルセットアップ(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;
    

    挿入

    並列DMLを有効にする 最初のステップで

    ALTER SESSION ENABLE PARALLEL DML;
    

    あるいは、ヒントを使用できることに注意してください

    INSERT /*+ ENABLE_PARALLEL_DML */ …
    

    さらに、強制した場合 並列DMLとQUERY、通常は並列ヒントを使用しません 。 APPENDで直接挿入することをほのめかしています これはこの状況でよく使用されます。

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

    テーブルが並列に挿入されたかどうかを確認する方法は?最も簡単な方法は、(コミットを行う前に)テーブルにクエリを実行することです。次のエラーが発生した場合は、並列直接挿入を行います。

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

    インデックス

    create indexで並列度を指定した場合 有効にする必要のないステートメント またはforce 何でも。

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

    チェックは、データディクショナリで学位を確認するのと同じくらい簡単です

    select DEGREE from user_indexes where table_name = 'TAB_HIST';
    
    DEGREE 
    --------- 
    2
    

    並列モードでインデックスを作成した後、DOPを1にリセットしたい場合が多いことに注意してください。そうしないと、いくつかの単純なネストされたループクエリが混乱し、並列クエリが開かれる可能性があります...



    1. MySql-最初に文字列値で並べ替え

    2. ONduplicatekeyUPDATE関数へのエラー挿入

    3. ネストされた順序なしリストを使用してツリーを構築する

    4. SQL行の戻り順序