2016-11-16 85 views
-1

有一个查询需要两分钟以上的时间。该查询的结果是960000行。 所以我使用提示。那么它只需要30秒。所以我在mybatis中应用查询并运行应用程序。但该查询需要两分多钟。所以我复制查询日志并粘贴本地开发人员。并执行查询。但只需要30秒。 我不知道........相同的查询,不同的表现

环境:春天,MyBatis的,甲骨文

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

解释计划是所有情况下的朋友。寻找表扫描和缺少索引。这是一个嵌入了大量业务逻辑的非常复杂的查询。 – duffymo

+1

在sql工具中执行查询或使用mybatis执行查询是完全不同的事情......查询可能仍然速度很快,但mybatis也会创建对象并使其放慢速度。所以你基本上比较不同的事情查询执行和查询执行+对象创建。 –

+0

对不起..只是执行时间。我检查了数据库服务器的查询时间。 – Jongho

回答

2

我已经遇到过这样的情况:时间差是不是在SQL查询执行,但取得结果。

Oracle JDBC驱动程序的默认获取大小为10,这意味着ResultSet会被馈送10行10行,这会在有100万条记录时进行大量往返数据库。提取大小必须增加。

使用PostgreSql时,默认的读取大小是无限的:ResultSet用整个结果提供(或直到OutOfMemory)。抓取大小可能需要降低。

要指定MyBatis中取大小值:

使用FETCHSIZE属性的XML select语句:

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

或者使用在注释FETCHSIZE选项:

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

范围在200-500之间的值通常是一个很好的折衷。

相关问题