2016-05-30 4 views
0

質問があります。INパラメータIFまたはELSEブロックの値に基づいてIF ELSE文が実行されている場合、ストアドプロシージャの実行計画はどのように作成されますかブロック内のクエリは同じテーブルから同じ値をフェッチしていますが、where句では異なるカラムを使用しています。IF ELSEの場合のOracleストアドプロシージャ実行プラン

私が知る限り、ストアドプロシージャごとに1つの実行計画しかありません。 JavaアプリケーションがプレーンJDBCを使用してストアドプロシージャを呼び出す場合、実行計画は最初に作成され、実行計画の作成にはブロック(IF)が実行されます。

次回は、ELSEブロックを実行すると同じ実行プランを使用するため、実行が遅くなります。

私は類似した呼び出しをしているので、この質問をしています。実行中の値と実行されたブロックに基づいて、実行された手順と実行時間は大きく異なります。

この場合、パフォーマンスを向上させるために何ができるのですか。 IF ELSEを使用する代わりに、別の手順を記述する必要があります。

PFBストアドプロシージャコード:

PACKAGE   COP00134_006_1 AS 
    TYPE t_cur_type IS REF CURSOR; 
    PROCEDURE GetConsignmentDetails(
     sPInputList  IN VARCHAR2, 
     sPInputType  IN VARCHAR2, 
     cPCon   OUT t_cur_type, 
     cPStatus  OUT t_cur_type, 
     sPError   OUT VARCHAR2); 
END COP00134_006_1; 

実装:

PACKAGE BODY   COP00134_006_1 AS 
    PROCEDURE GetConsignmentDetails(
     sPInputList  IN VARCHAR2, 
     sPInputType  IN VARCHAR2, 
     cPCon   OUT t_cur_type, 
     cPStatus  OUT t_cur_type, 
     sPError   OUT VARCHAR2) 
    IS 
    BEGIN 
     sPError := '0'; 
     IF sPInputType = 'CON' THEN 
     OPEN cPCon FOR 
      SELECT 
        con_id 
        ,con_legacy_id 
        ,con_create_td 
        ,con_pickup_lt 
        ,con_deliv_due_lt 
        ,CON_DELIV_END_LT 
        ,SRP_ID_AREA_DEST 
        ,CON_CLNT_REF_TX 
        ,BUL_CSYS_ID_ORIG 
        ,BUL_ID_ORIG 
        ,BUL_NM_ORIG 
        ,BUL_NM_DEST 
        ,cpn_oa_town_nm_r 
        ,cpn_oa_town_nm_d 
        ,cou_iso_id_orig 
        ,Cou_Nm_Orig 
        ,cou_iso_id_dest 
        ,Cou_Nm_Dest 
        ,PCE_QT 
        ,DUPLICATES 
        ,COS_SIGN_NM FROM (
      SELECT /*+ cardinality (b 3) */ 
        co.con_id 
        ,co.con_legacy_id 
        ,co.con_create_td 
        ,co.con_pickup_lt 
        ,co.con_deliv_due_lt 
        ,co.CON_DELIV_END_LT 
        ,co.SRP_ID_AREA_DEST 
        ,co.CON_CLNT_REF_TX 
        ,co.BUL_CSYS_ID_ORIG 
        ,blOrig.BUL_ID as BUL_ID_ORIG 
        ,blOrig.BUL_NM as BUL_NM_ORIG 
        ,blDest.BUL_NM as BUL_NM_DEST 
        ,cnr.cpn_oa_town_nm as cpn_oa_town_nm_r 
        ,cnd.cpn_oa_town_nm as cpn_oa_town_nm_d 
        ,co.cou_iso_id_orig 
        ,cuOrig.Cou_nm as Cou_Nm_Orig 
        ,co.cou_iso_id_dest 
        ,cuDest.Cou_nm as Cou_Nm_Dest 
        ,(select count(*) from CORPCV01 PC WHERE PC.CON_ID = CO.CON_ID) PCE_QT 
        ,CASE WHEN COUNT(*) OVER(PARTITION BY CON_LEGACY_ID) > 1 THEN 'TRUE' ELSE 'FALSE' END AS DUPLICATES 
        ,cs.COS_SIGN_NM, ROW_NUMBER() OVER(PARTITION BY CS.CON_ID ORDER BY COS_EVENT_TD) SEQ_NR 
       FROM corcov01 co 
       INNER JOIN corcnv01 cnr 
       ON cnr.con_id = co.con_id 
       AND cnr.cpn_type_cd = 'R' 
       LEFT OUTER JOIN corcnv01 cnd 
       ON cnd.con_id = co.con_id 
       AND cnd.cpn_type_cd = 'D' 
       INNER JOIN ncrcuv01 cuOrig 
       ON cuOrig.COU_ISO_ID = co.COU_ISO_ID_ORIG 
       AND TRUNC(CURRENT_DATE) BETWEEN cuOrig.COU_EFFECT_DT AND cuOrig.COU_EFFECT_TO_DT 
       INNER JOIN ncrcuv01 cuDest 
       ON cuDest.COU_ISO_ID = co.COU_ISO_ID_DEST 
       AND TRUNC(CURRENT_DATE) BETWEEN cuDest.COU_EFFECT_DT AND cuDest.COU_EFFECT_TO_DT 
       LEFT OUTER JOIN ncrblv01 blOrig 
       ON blOrig.BUL_CSYS_ID = co.BUL_CSYS_ID_ORIG 
       AND TRUNC(CURRENT_DATE) BETWEEN blOrig.BUL_EFFECT_DT AND blOrig.BUL_EFFECT_TO_DT 
       LEFT OUTER JOIN ncrblv01 blDest 
       ON blDest.BUL_CSYS_ID = co.BUL_CSYS_ID_DEST 
       AND TRUNC(CURRENT_DATE) BETWEEN blDest.BUL_EFFECT_DT AND blDest.BUL_EFFECT_TO_DT 
       LEFT OUTER JOIN corcsv01 cs 
       ON co.con_id = cs.con_id 
       AND cs.cos_sign_nm is not null 
       and cs.cos_delete_in = 'N' 
       WHERE co.con_Legacy_Id IN (select dataItem from TABLE(ZYADMIN.ZYP90008.GetListFromCSV(sPInputList)) b) 
       )WHERE SEQ_NR = 1; 
      OPEN cPStatus FOR 
       SELECT csv.CON_ID AS CON_ID_COS 
        ,csv.XSF_ID 
        ,csv.XSS_ID 
        ,csv.XSG_ID 
        ,csv.XSD_ID 
        ,ndv.XSX_ID 
        ,ndv.xsd_customer_ds 
        ,BUL_CSYS_ID_OCC 
        ,nlv.BUL_NM as BUL_NM_OCC 
        ,csv.COS_EVENT_LT 
        ,ndv.XSD_SEVERITY_CD 
        ,qb.QLA_DS 
       FROM corcsv01 csv 
       INNER JOIN corcov01 co 
        ON csv.con_id = co.con_id 
       INNER JOIN ncrsdv01 ndv 
        ON ndv.XSF_ID=csv.XSF_ID 
       AND ndv.XSS_ID=csv.XSS_ID 
       AND ndv.XSG_ID=csv.XSG_ID 
       AND ndv.XSD_ID=csv.XSD_ID 
       AND TRUNC(CURRENT_DATE) BETWEEN ndv.XSD_EFFECT_DT AND ndv.XSD_EFFECT_TO_DT 
       INNER JOIN ncrksv01 ks 
        ON ndv.XSX_ID= ks.XSX_ID 
       AND TRUNC(CURRENT_DATE) BETWEEN ks.SKT_EFFECT_DT AND ks.SKT_EFFECT_TO_DT 
       AND ks.SCA_ID = 'WEB' 
       LEFT OUTER JOIN ncrqav01 qa 
       ON qa.XSX_ID = ndv.XSX_ID 
       AND qa.APP_ID = 'EXCO' 
       AND TRUNC(CURRENT_DATE) BETWEEN QAS_EFFECT_DT AND QAS_EFFECT_TO_DT 
       LEFT OUTER JOIN ncrqbv01 qb 
       ON qa.QLA_ID = qb.QLA_ID 
       AND qa.APP_ID = qb.APP_ID 
       AND TRUNC(CURRENT_DATE) BETWEEN QLA_EFFECT_DT AND QLA_EFFECT_TO_DT 
       INNER JOIN ncrblv01 nlv 
        ON nlv.BUL_CSYS_ID=csv.BUL_CSYS_ID_OCC 
       AND TRUNC(CURRENT_DATE)BETWEEN nlv.BUL_EFFECT_DT AND nlv.BUL_EFFECT_TO_DT 
       WHERE co.con_Legacy_Id IN (select dataItem from TABLE(ZYADMIN.ZYP90008.GetListFromCSV(sPInputList)) b); 
     ELSE 
     OPEN cPCon FOR 
        SELECT 
        con_id 
        ,con_legacy_id 
        ,con_create_td 
        ,con_pickup_lt 
        ,con_deliv_due_lt 
        ,CON_DELIV_END_LT 
        ,SRP_ID_AREA_DEST 
        ,CON_CLNT_REF_TX 
        ,BUL_CSYS_ID_ORIG 
        ,BUL_ID_ORIG 
        ,BUL_NM_ORIG 
        ,BUL_NM_DEST 
        ,cpn_oa_town_nm_r 
        ,cpn_oa_town_nm_d 
        ,cou_iso_id_orig 
        ,Cou_Nm_Orig 
        ,cou_iso_id_dest 
        ,Cou_Nm_Dest 
        ,PCE_QT 
        ,DUPLICATES 
        ,COS_SIGN_NM FROM (
      SELECT /*+ cardinality (b 3) */ 
        co.con_id 
        ,co.con_legacy_id 
        ,co.con_create_td 
        ,co.con_pickup_lt 
        ,co.con_deliv_due_lt 
        ,co.CON_DELIV_END_LT 
        ,co.SRP_ID_AREA_DEST 
        ,co.CON_CLNT_REF_TX 
        ,co.BUL_CSYS_ID_ORIG 
        ,blOrig.BUL_ID as BUL_ID_ORIG 
        ,blOrig.BUL_NM as BUL_NM_ORIG 
        ,blDest.BUL_NM as BUL_NM_DEST 
        ,cnr.cpn_oa_town_nm as cpn_oa_town_nm_r 
        ,cnd.cpn_oa_town_nm as cpn_oa_town_nm_d 
        ,co.cou_iso_id_orig 
        ,cuOrig.Cou_nm as Cou_Nm_Orig 
        ,co.cou_iso_id_dest 
        ,cuDest.Cou_nm as Cou_Nm_Dest 
        ,(select count(*) from CORPCV01 PC WHERE PC.CON_ID = CO.CON_ID) PCE_QT 
        ,'FALSE' AS DUPLICATES 
        ,cs.COS_SIGN_NM, ROW_NUMBER() OVER(PARTITION BY CS.CON_ID ORDER BY COS_EVENT_TD) SEQ_NR 
       FROM corcov01 co 
       INNER JOIN corcnv01 cnr 
       ON cnr.con_id = co.con_id 
       AND cnr.cpn_type_cd = 'R' 
       LEFT OUTER JOIN corcnv01 cnd 
       ON cnd.con_id = co.con_id 
       AND cnd.cpn_type_cd = 'D' 
       INNER JOIN ncrcuv01 cuOrig 
       ON cuOrig.COU_ISO_ID = co.COU_ISO_ID_ORIG 
       AND TRUNC(CURRENT_DATE) BETWEEN cuOrig.COU_EFFECT_DT AND cuOrig.COU_EFFECT_TO_DT 
       INNER JOIN ncrcuv01 cuDest 
       ON cuDest.COU_ISO_ID = co.COU_ISO_ID_DEST 
       AND TRUNC(CURRENT_DATE) BETWEEN cuDest.COU_EFFECT_DT AND cuDest.COU_EFFECT_TO_DT 
       LEFT OUTER JOIN ncrblv01 blOrig 
       ON blOrig.BUL_CSYS_ID = co.BUL_CSYS_ID_ORIG 
       AND TRUNC(CURRENT_DATE) BETWEEN blOrig.BUL_EFFECT_DT AND blOrig.BUL_EFFECT_TO_DT 
       LEFT OUTER JOIN ncrblv01 blDest 
       ON blDest.BUL_CSYS_ID = co.BUL_CSYS_ID_DEST 
       AND TRUNC(CURRENT_DATE) BETWEEN blDest.BUL_EFFECT_DT AND blDest.BUL_EFFECT_TO_DT 
       LEFT OUTER JOIN corcsv01 cs 
       ON co.con_id = cs.con_id 
       AND cs.cos_sign_nm is not null 
       and cs.cos_delete_in = 'N' 
       WHERE co.CON_CLNT_REF_CR IN (select dataItem from TABLE(ZYADMIN.ZYP90008.GetListFromCSV(sPInputList)) b) 
       )WHERE SEQ_NR = 1; 
      OPEN cPStatus FOR 
       SELECT csv.CON_ID AS CON_ID_COS 
        ,csv.XSF_ID 
        ,csv.XSS_ID 
        ,csv.XSG_ID 
        ,csv.XSD_ID 
        ,ndv.XSX_ID 
        ,ndv.xsd_customer_ds 
        ,BUL_CSYS_ID_OCC 
        ,nlv.BUL_NM as BUL_NM_OCC 
        ,csv.COS_EVENT_LT 
        ,ndv.XSD_SEVERITY_CD 
        ,qb.QLA_DS 
       FROM corcsv01 csv 
       INNER JOIN corcov01 co 
        ON csv.con_id = co.con_id 
       INNER JOIN ncrsdv01 ndv 
        ON ndv.XSF_ID=csv.XSF_ID 
       AND ndv.XSS_ID=csv.XSS_ID 
       AND ndv.XSG_ID=csv.XSG_ID 
       AND ndv.XSD_ID=csv.XSD_ID 
       AND TRUNC(CURRENT_DATE) BETWEEN ndv.XSD_EFFECT_DT AND ndv.XSD_EFFECT_TO_DT 
       INNER JOIN ncrksv01 ks 
        ON ndv.XSX_ID= ks.XSX_ID 
       AND TRUNC(CURRENT_DATE) BETWEEN ks.SKT_EFFECT_DT AND ks.SKT_EFFECT_TO_DT 
       AND ks.SCA_ID = 'WEB' 
       LEFT OUTER JOIN ncrqav01 qa 
       ON qa.XSX_ID = ndv.XSX_ID 
       AND qa.APP_ID = 'EXCO' 
       AND TRUNC(CURRENT_DATE) BETWEEN QAS_EFFECT_DT AND QAS_EFFECT_TO_DT 
       LEFT OUTER JOIN ncrqbv01 qb 
       ON qa.QLA_ID = qb.QLA_ID 
       AND qa.APP_ID = qb.APP_ID 
       AND TRUNC(CURRENT_DATE) BETWEEN QLA_EFFECT_DT AND QLA_EFFECT_TO_DT 
       INNER JOIN ncrblv01 nlv 
        ON nlv.BUL_CSYS_ID=csv.BUL_CSYS_ID_OCC 
       AND TRUNC(CURRENT_DATE)BETWEEN nlv.BUL_EFFECT_DT AND nlv.BUL_EFFECT_TO_DT 
       WHERE co.CON_CLNT_REF_CR IN (select dataItem from TABLE(ZYADMIN.ZYP90008.GetListFromCSV(sPInputList)) b); 
     END IF; 
    EXCEPTION 
     WHEN OTHERS THEN 
      sPError := '1' ||' '||SQLCODE||' '||SUBSTR(SQLERRM, 1, 200); 
    END; 
END COP00134_006_1; 

問題が他の部分で実行されるクエリです。 コメントで述べたように、私は同じクエリを別々に実行しており、1秒未満で実行され、同じデータがプロシージャに渡されると1分以上かかります。私はデータベースアクセスがないためプロファイラを実行できません。DBAに問い合わせるプロセスには1週間以上かかるので、できるだけ早くこの問題を解決する必要があります

+0

AFAI、はい、DBからjdbc経由でデータを取得する際にパフォーマンス上の問題がある場合は、 –

+2

SQL問合せには、ストアド・プロシージャ(またはそのようなコードのPL/SQLブロック)ではなく、実行計画があります。したがって、実行計画はストアドプロシージャ内のクエリごとに考慮されます。あなたはそれを記述する方法で問題を経験することはありません。 – sstan

+0

@cihanseven - あなたが何を意味するかわかりません。 JDBCは、適切に構成されていれば、優れたパフォーマンスが得られます。 – APC

答えて

0

Oracleはストアドプロシージャではなくクエリの実行計画をビルドします。したがって、ストアドプロシージャの各クエリには独自の実行計画があります。あなたはyoourクエリについてはこれを言う:

異なる列の異なるアクセス・パスを意味し、「句はどこにある別の列に」:これは、インデックスの異なる使用につながるかもしれないが、別のディスクには活動を読んで、潜在的に異なる量のデータ。したがって、IF ... ELSEのどの支店に応じて異なるパフォーマンスを経験するのは驚くことではありません。別の手順を実行しても、基礎となるクエリのパフォーマンスは変わりません。

違いを調べるには、個々のクエリごとにEXPLAIN PLANを実行します。 Find out more。ステートメントをSQLワークシート(またはSQLの操作に使用するツール)に貼り付ける必要があります。


問題がストアド・プロシージャにあると思う場合は、PL/SQLプロファイラを使用して時間がどこにあるか調べてください。 Find out more。まだインストールされていない場合は、おそらくDBAをインストールする必要があります。


「同じクエリが同じ値を持つストアド・プロシージャ内で実行され、同じデータに、それは60 +秒を取っている」

あなたは経過時間の話を続けます。どのようにこれらを測定していますか?あなたは何を測定していますか?時間はどこに行くの?実際の原因がshonky JDBC構成の悪いネットワーク接続であった場合、パフォーマンスが低下したためデータベースが非難されたのは初めてではありません。

+0

私は個々のクエリの説明を実行しており、説明はうまくいきます。また、クエリは0.5秒未満で実行されています。しかし、同じクエリが同じ値で同じプロシージャ内で実行され、同じデータに対して60秒以上かかる場合、 – Neel

+0

StackOverflowの人々がこれまでに提供した情報でできることの限界に達しました。診断には手がかりが必要です。コード、生データ、サンプルの入力と出力、計画とプロファイルの説明が必要です。 – APC

+0

私はストアドプロシージャコードを追加しました。私は何かを得ることができるといいですね。 – Neel

関連する問題