2016-11-16 19 views
-1

2分以上かかるクエリがあります。そのクエリの結果は960000行です。 私はヒントを使用します。わずか30秒かかります。私はmybatisでクエリを適用し、アプリケーションを実行します。そのクエリは2分以上かかる。だから私はログにクエリをコピーし、ローカル開発者を貼り付けます。クエリを実行します。 30秒しかかかりません。私はすでにこのような状況を満たしている同じクエリ、異なるパフォーマンス

SELECT * 
FROM (
    SELECT /*+ USE_HASH(a b c) */ ROW_NUMBER() OVER(ORDER BY A.TRANS_DT DESC, A.TRANS_TM DESC) AS RNUM      
      ,A.PAY_METHOD 
      ,B.BRAND_NM 
      ,A.I_MID         
      ,C.TRANS_DT 
      ,C.TRANS_TM 
      ,C.TRANS_DT || C.TRANS_TM AS TRANS_DTM 
      ,C.VACCT_VALID_DT       
      ,C.VACCT_VALID_TM       
      ,C.VACCT_VALID_DT||C.VACCT_VALID_TM AS VACCT_VALID_DTM 
      ,NVL(C.DEPOSIT_DT, ' ') DEPOSIT_DT      
      ,NVL(C.DEPOSIT_TM, ' ') DEPOSIT_TM      
      ,NVL(C.DEPOSIT_DT, ' ')||NVL(C.DEPOSIT_TM, ' ') AS DEPOSIT_DTM  
      ,NVL(C.DEPOSIT_AMT, 0) AS AMT          
      ,NVL(A.AMT, 0) AS INPUT_AMT          
      ,A.BANK_CD               
      ,IONPAY.UF_GET_BANK_NAME(A.BANK_CD) AS BANK_CD_NM     
      ,C.VACCT_NO             
      ,A.BILLING_NM           
      ,A.REFERENCE_NO          
      ,A.TXID           
      ,A.STATUS   
      ,NVL(A.STATUS, ' ') AS INPUT_STATUS  
      ,IONPAY.UF_GET_TRANS_VACCT_STATUS_NAME(C.STATUS) AS INPUT_STATUS_NAME 
      ,C.STATUS AS TRANS_STATUS 
      ,IONPAY.UF_GET_TRANS_VACCT_STA_NAME_2(C.STATUS, C.MATCH_CL, C.VACCT_VALID_DT, C.VACCT_VALID_TM) AS STATUS_NAME 
      ,A.ACQU_STATUS     
      ,A.CANCEL_DT||A.CANCEL_TM AS REVERSAL_DATE 
      ,NVL((SELECT DESC2 
        FROM TB_CODE 
        WHERE CODE_CL = 'CHNL' 
         AND CODE1 = C.BANK_CD 
         AND CODE2 = C.CHANNEL_TYPE), ' ') AS channel 
    FROM TB_TRANS_HISTORY A, TB_BO_MER_MGMT B, TB_VACCT_TRANS C 
    WHERE A.I_MID = B.I_MID 
     AND A.TXID = C.TXID 
     AND A.I_MID = C.I_MID 
     AND B.I_MID = C.I_MID 
     AND A.PAY_METHOD IN ('02') 
     AND A.TRANS_DT BETWEEN '20161016' AND '20161116' 
     AND A.TRANS_DT||A.TRANS_TM BETWEEN '2016101600%3A0000' AND '2016111624%3A0000'  
     AND B.TAX_NO != 'NICEPAY' 
     AND C.SIMULATION_FLG = '0' 
     AND C.STATUS IN ('0', '1', '2', '3', '4') 
) TBL 
WHERE RNUM BETWEEN 210000 AND 220000 
+2

すべての場合、EXPLAIN PLANはあなたの友人です。テーブルスキャンと欠落しているインデックスを探します。これは、非常に複雑なクエリであり、多くのビジネスロジックが埋め込まれています。 – duffymo

+1

SQLツールでクエリを実行するか、mybatisで実行するかはまったく異なります...クエリはおそらくまだ高速ですが、mybatisもオブジェクトを作成し、処理速度を低下させます。つまり、基本的には、実行中の問合せと実行中の問合せ+オブジェクトの作成を比較しています。 –

+0

申し訳ありません。私はdbサーバーのクエリのexcuting時間を確認しました。 – Jongho

答えて

2

春、MyBatisの、オラクル::私は知りません ........

環境の時間差は、SQLクエリの実行ではありませんが、結果を取得する。

Oracle JDBCドライバのデフォルトフェッチサイズは10です。つまり、ResultSetには10行×10行が指定され、100万レコードがある場合にDBへのラウンドトリップが多く発生します。フェッチサイズを大きくする必要があります。

PostgreSQLでは、デフォルトのフェッチサイズは無制限です。ResultSetには結果全体(またはOutOfMemoryまで)が与えられます。フェッチサイズを小さくする必要があります。

MyBatisの中フェッチサイズの値を指定するには:

使用して、XML select文でのfetchSize属性:

<select id="listItems" fetchSize="300">SELECT ...</select> 

や注釈でのfetchSizeオプションを使用します。

@Select("SELECT ...") 
@Options(fetchSize=300) 

を200〜500の範囲の値は、しばしば良い妥協点です。

関連する問題