2017-01-04 15 views
0

SQLクエリを最適化するのに苦労します.SQLクエリを完了するのに約1分かかります。ここでは、クエリは次のとおりです。ビュー(&インデックス)を使用したSQLクエリの最適化

SELECT mpg.ID_PROD_GARN, mpg.NO_PROD 
FROM ACO.prime p 
JOIN ACO.facture_compt fc 
ON fc.id_factr = p.id_factr 
JOIN ACO.V_CONTRAT vc 
ON vc.NO_POLC = p.NO_POLC 
JOIN ACO.MV_PRODUIT mp 
ON mp.NO_PROD =vc.NO_PROD 
JOIN ACO.MV_PROD_GARN mpg 
ON mpg.NO_PROD = mp.NO_PROD 
WHERE p.id_prime = 
(SELECT MAX(id_prime) AS prime FROM ACO.prime p WHERE p.no_polc='T3167978') 
AND mpg.ID_PROD_GARN = '1238' 
AND fc.cd_stat_factr = 'comp'; 

V_CONTRATは図であり、(私の理解が正しければ)結果を見つけるために、トラフすべての行を実行しているこのようにSQLビューを結合するとき。私は少しの研究を行い、このビューのインデックスを作成するとクエリが高速化できることがわかりました。したがって:

CREATE INDEX indx_no_produit ON ACO.V_CONTRAT(NO_PROD); 

残念ながら、私はビューのインデックスを作成できませんというエラーが表示されます。SQL:ORA-01702:ここでは使用できません。 *原因:他の考えられる原因の中で、 がビュー上でエディション・ビューを定義しようとしたときに、このメッセージが生成されます。 *処置:エディション・ビューは、基本表に対してのみ作成できます。

私の質問はどのように私はこのクエリをエレガントにスピードアップできますか?

事前に感謝します。

編集1:ここで説明する計画が

計画ハッシュ値である:3107129748

------------------------------------------------------------------------------------------------------------------------- 
| Id | Operation       | Name      | Rows | Bytes |TempSpc| Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT     |       |  1 | 102 |  | 543K (1)| 00:00:22 | 
| 1 | NESTED LOOPS      |       |  1 | 102 |  | 543K (1)| 00:00:22 | 
| 2 | NESTED LOOPS      |       |  1 | 90 |  | 543K (1)| 00:00:22 | 
| 3 | NESTED LOOPS     |       |  1 | 35 |  |  3 (0)| 00:00:01 | 
| 4 |  NESTED LOOPS     |       |  1 | 14 |  |  2 (0)| 00:00:01 | 
| 5 |  MAT_VIEW ACCESS BY INDEX ROWID| MV_PROD_GARN    |  1 |  9 |  |  1 (0)| 00:00:01 | 
|* 6 |  INDEX UNIQUE SCAN   | PK_PROG     |  1 |  |  |  1 (0)| 00:00:01 | 
| 7 |  BITMAP CONVERSION TO ROWIDS |       |  1 |  5 |  |  1 (0)| 00:00:01 | 
|* 8 |  BITMAP INDEX FAST FULL SCAN | MV_PROD_NO_PROD_IDX  |  |  |  |   |   | 
| 9 |  TABLE ACCESS BY INDEX ROWID | PRIME      |  1 | 21 |  |  1 (0)| 00:00:01 | 
|* 10 |  INDEX UNIQUE SCAN    | PK_PRIME     |  1 |  |  |  1 (0)| 00:00:01 | 
| 11 |  SORT AGGREGATE    |       |  1 | 15 |  |   |   | 
| 12 |  FIRST ROW     |       |  1 | 15 |  |  1 (0)| 00:00:01 | 
|* 13 |   INDEX RANGE SCAN (MIN/MAX) | PRIME_NO_POLC_IDX   |  1 | 15 |  |  1 (0)| 00:00:01 | 
|* 14 | VIEW       | V_CONTRAT     |  1 | 55 |  | 543K (1)| 00:00:22 | 
| 15 |  SORT UNIQUE     |       | 16M| 5011M| 2740M| 543K (1)| 00:00:22 | 
| 16 |  UNION-ALL      |       |  |  |  |   |   | 
|* 17 |  HASH JOIN     |       | 16M| 2502M|  | 55963 (4)| 00:00:03 | 
| 18 |  VIEW      | index$_join$_016   | 103 | 1339 |  |  2 (0)| 00:00:01 | 
|* 19 |   HASH JOIN     |       |  |  |  |   |   | 
| 20 |   INDEX FAST FULL SCAN  | PK_PROD     | 103 | 1339 |  |  1 (0)| 00:00:01 | 
| 21 |   INDEX FAST FULL SCAN  | PRODUIT_COMBINE_IDX  | 103 | 1339 |  |  1 (0)| 00:00:01 | 
|* 22 |  HASH JOIN RIGHT OUTER  |       | 16M| 2293M| 261M| 55860 (4)| 00:00:03 | 
| 23 |   INDEX FAST FULL SCAN  | ROL_INDEX1     | 10M| 145M|  | 5703 (2)| 00:00:01 | 
|* 24 |   HASH JOIN RIGHT OUTER  |       | 6751K| 824M| 117M| 44540 (4)| 00:00:02 | 
| 25 |   INLIST ITERATOR   |       |  |  |  |   |   | 
|* 26 |   INDEX RANGE SCAN   | ROL_CDROL_NOINTR_IDX  | 3975K| 72M|  | 756 (2)| 00:00:01 | 
|* 27 |   HASH JOIN RIGHT OUTER  |       | 4192K| 435M| 90M| 40898 (3)| 00:00:02 | 
|* 28 |   TABLE ACCESS FULL  | ROLE      | 2881K| 57M|  | 14553 (4)| 00:00:01 | 
|* 29 |   HASH JOIN    |       | 2941K| 246M| 104M| 24558 (3)| 00:00:01 | 
| 30 |   INDEX FAST FULL SCAN | INFO_BASE_DISTRIBUTEUR_FK1 | 4047K| 57M|  | 1925 (2)| 00:00:01 | 
|* 31 |   HASH JOIN    |       | 2961K| 206M| 136M| 20967 (3)| 00:00:01 | 
| 32 |    TABLE ACCESS FULL  | CONTRAT_ITER    | 4088K| 89M|  | 12159 (2)| 00:00:01 | 
|* 33 |    HASH JOIN RIGHT OUTER |       | 2961K| 141M| 32M| 7292 (3)| 00:00:01 | 
|* 34 |    INDEX RANGE SCAN  | ROL_CDROL_NOINTR_IDX  | 933K| 22M|  | 890 (1)| 00:00:01 | 
|* 35 |    TABLE ACCESS FULL  | CONTRAT     | 2615K| 62M|  | 5781 (3)| 00:00:01 | 
|* 36 |  HASH JOIN OUTER    |       | 29239 | 2912K|  | 10228 (3)| 00:00:01 | 
|* 37 |  HASH JOIN     |       | 29239 | 1941K|  | 285 (2)| 00:00:01 | 
| 38 |   TABLE ACCESS FULL   | DISTRIBUTEUR    | 9142 | 91420 |  | 45 (3)| 00:00:01 | 
|* 39 |   HASH JOIN     |       | 29239 | 1656K|  | 240 (1)| 00:00:01 | 
| 40 |   INDEX FULL SCAN   | PRODUIT_COMBINE_IDX  | 103 | 1030 |  |  1 (0)| 00:00:01 | 
|* 41 |   TABLE ACCESS FULL   | TPA_CONTRAT_MENSUEL  | 29239 | 1370K|  | 239 (1)| 00:00:01 | 
| 42 |  TABLE ACCESS FULL   | COUNTERPARTY    | 3547K| 115M|  | 9921 (2)| 00:00:01 | 
|* 43 | INDEX RANGE SCAN     | FACTURE_COMPT_INDEX9  |  1 | 12 |  |  1 (0)| 00:00:01 | 
------------------------------------------------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    6 - access("MPG"."ID_PROD_GARN"=1238) 
    8 - filter("MPG"."NO_PROD"="MP"."NO_PROD") 
    10 - access("P"."ID_PRIME"= (SELECT MAX("ID_PRIME") FROM "ACO"."PRIME" "P" WHERE "P"."NO_POLC"='T3167978')) 
    13 - access("P"."NO_POLC"='T3167978') 
    14 - filter("VC"."NO_POLC"="P"."NO_POLC" AND "MP"."NO_PROD"="VC"."NO_PROD") 
    17 - access("PROD"."NO_PROD"="ITER"."NO_PROD" AND "PROD"."NO_VERS_PROD"="ITER"."NO_VERS_PROD") 
    19 - access(ROWID=ROWID) 
    22 - access("ROLAUTRE"."ID_CONT"(+)="CONT"."ID_CONT" AND "ROLAUTRE"."NO_ITER_CONT"(+)="CONT"."NO_DERN_ITER") 
    24 - access("ROLA"."ID_CONT"(+)="CONT"."ID_CONT" AND "ROLA"."NO_ITER_CONT"(+)="CONT"."NO_DERN_ITER") 
    26 - access("ROLA"."CD_ROLE"(+)='ap' OR "ROLA"."CD_ROLE"(+)='debit' OR "ROLA"."CD_ROLE"(+)='emprun') 
    27 - access("ROLPAY"."ID_CONT"(+)="CONT"."ID_CONT" AND "ROLPAY"."NO_ITER_CONT"(+)="CONT"."NO_DERN_ITER") 
    28 - filter("ROLPAY"."CD_ROLE"(+)='pay' AND "ROLPAY"."IND_PAY_PRI"(+)='1') 
    29 - access("ITER"."ID_INFO_BASE"="IB"."ID_INFO_BASE" AND "ITER"."NO_ITER_CONT"="IB"."NO_ITER_CONT" AND 
       SYS_OP_DESCEND("ITER"."NO_ITER_CONT")=SYS_OP_DESCEND("IB"."NO_ITER_CONT")) 
    31 - access("ITER"."ID_CONT"="CONT"."ID_CONT" AND "ITER"."NO_ITER_CONT"="CONT"."NO_DERN_ITER" AND 
       SYS_OP_DESCEND("ITER"."NO_ITER_CONT")=SYS_OP_DESCEND("CONT"."NO_DERN_ITER")) 
    33 - access("ROLP"."ID_CONT"(+)="CONT"."ID_CONT" AND "ROLP"."NO_ITER_CONT"(+)="CONT"."NO_DERN_ITER") 
    34 - access("ROLP"."CD_ROLE"(+)='pren') 
    35 - filter("CONT"."NO_SEQ_PROPO_SEL"=0) 
    36 - access("CTRPY"."LAST_NAME"(+)="TCM"."CON_NOM_ASS_PRINC" AND 
       "CTRPY"."FRST_NAME"(+)="TCM"."CON_PRENOM_ASS_PRINC" AND "CTRPY"."DT_BIRTH"(+)="TCM"."CON_DATE_NAISS_ASS_PRINC") 
    37 - access("TCM"."CON_NO_DISTRIBUTEUR"="A"."NO_DIST") 
    39 - access("PROD"."NO_PROD"="TCM"."CON_CODE_PRODDUIT") 
    41 - filter("TCM"."CON_VERSION_CONTRAT"=1) 
    43 - access("FC"."ID_FACTR"="P"."ID_FACTR" AND "FC"."CD_STAT_FACTR"='comp') 

編集2:ここでは、ビューV_CONTRATは

SELECT DISTINCT cont.ID_CONT, 
        cont.NO_POLC, 
        cont.cd_divs, 
        prod.no_prod, 
        prod.cd_cie_encai, 
        prod.cd_faml_cptb, 
        ib.no_dist_init, 
        CASE 
         WHEN ROLP.ID_ROLE IS NOT NULL THEN ROLP.NO_INTR 
         WHEN rola.no_intr IS NOT NULL THEN rola.no_intr 
         WHEN rolpay.no_intr IS NOT NULL THEN rolpay.no_intr 
         ELSE rolAutre.no_intr 
        END 
         AS NO_INTR_PRINC, 
        rolpay.no_intr AS NO_INTR_PAY 
    FROM      VIRAGE.CONTRAT CONT 
           INNER JOIN 
           VIRAGE.contrat_iter iter 
           ON  iter.id_cont = cont.id_cont 
           AND ITER.NO_ITER_CONT = CONT.NO_DERN_ITER 
           AND CONT.NO_SEQ_PROPO_SEL = 0 
          INNER JOIN 
           VIRAGE.info_base ib 
          ON iter.id_info_base = ib.id_info_base 
           AND iter.no_iter_cont = ib.no_iter_cont 
         INNER JOIN 
          VIRAGE.produit prod 
         ON prod.no_prod = iter.no_prod 
          AND prod.no_vers_prod = iter.no_vers_prod 
        LEFT JOIN 
         VIRAGE.role rolp 
        ON  rolp.id_cont = cont.id_cont 
         AND rolp.no_iter_cont = cont.no_dern_iter 
         AND rolp.cd_role = 'pren' 
        LEFT JOIN 
        VIRAGE.role rola 
        ON rola.id_cont = cont.id_cont 
        AND rola.no_iter_cont = cont.no_dern_iter 
        AND ( rola.cd_role = 'ap' 
          OR ROLA.CD_ROLE = 'debit' 
          OR rola.cd_role = 'emprun') 
       LEFT JOIN 
        VIRAGE.role rolpay 
       ON  rolpay.id_cont = cont.id_cont 
        AND rolpay.no_iter_cont = cont.no_dern_iter 
        AND rolpay.cd_role = 'pay' 
        AND rolpay.ind_pay_pri = '1' 
      LEFT JOIN 
       VIRAGE.role rolAutre 
      ON rolAutre.id_cont = cont.id_cont 
       AND rolAutre.no_iter_cont = cont.no_dern_iter 
    UNION 
    SELECT DISTINCT 
      CAST (tcm.con_sequence AS NUMBER (10, 0)) AS id_cont, 
      CAST (tcm.con_numero_contrat AS VARCHAR2 (20)) AS no_polc, 
      CAST (vd.cd_divs_compt AS VARCHAR2 (11)) AS cd_divs, 
      CAST (tcm.con_code_prodduit AS NUMBER (5, 0)) AS no_prod, 
      CAST (prod.cd_cie_encai AS VARCHAR2 (1)) AS cd_cie_encai, 
      CAST (prod.cd_faml_cptb AS VARCHAR2 (11)) AS cd_faml_cptb, 
      CAST (tcm.con_no_distributeur AS VARCHAR2 (15)) AS no_dist_init, 
      CAST (ctrpy.no_ctrpy AS NUMBER) AS no_intr_princ, 
      CAST (ctrpy.no_ctrpy AS NUMBER) AS no_intr_pay 
    FROM   TPA.TPA_CONTRAT_MENSUEL tcm 
        INNER JOIN 
        VIRAGE.produit prod 
        ON prod.no_prod = tcm.con_code_prodduit 
       LEFT JOIN 
        counterparty ctrpy 
       ON  ctrpy.last_name = tcm.con_nom_ass_princ 
        AND ctrpy.frst_name = tcm.con_prenom_ass_princ 
        AND ctrpy.dt_birth = tcm.con_date_naiss_ass_princ 
      INNER JOIN 
       v_distributeur vd 
      ON tcm.con_no_distributeur = vd.no_dist 
      WHERE TCM.CON_VERSION_CONTRAT=1 
+0

マテリアライズド・ビューは役に立ちますか?マテリアライズド・ビューに関する調査を少し行います。マテリアライズド・ビューに索引を付けることができることに加えて、「高速リフレッシュ」が役立ちます。あなたがDBAでない場合は、DBAと話し合う必要があるかもしれません。 – mathguy

+1

問合せの実行計画は、問合せを最適化する際に必要です。 'EXPLAIN PLAN FOR FOR your_query'を実行してから' SELECT * FROM table(DBMS_xplan.Display) 'を実行し、最後に**最後のクエリの**結果をコピーして、**そのテキストをプレーンテキストとして質問に追加してください - ビットマップではありません!!! **。ここで見つけることができる説明計画の詳細:https://docs.oracle.com/cd/B28359_01/server.111/b28274/ex_plan.htm#i3305 – krokodilko

+1

ビューを索引付けしません。索引を作成する必要があります。問題の基礎となる表の列 – OldProgrammer

答えて

0

インデックスはテーブルのみで作成することができています。

テーブルごとに1つの外部キーごとにインデックスを作成してください。他のシステムと同じように、デフォルトでOracleは作成しません。

サブクエリのパフォーマンスもチェックし、時間がかかる場合は、WHERE句のすべての属性のインデックスも作成する必要があります。

インデックスにメンテナンスが必要であることを忘れないでください。

関連する問題