2016-11-16 15 views
-1

Существует запрос, который занимает более двух минут. этот результат запроса составляет 960000 строк. поэтому я использую подсказку. то это займет всего 30 секунд. поэтому я применил запрос в mybatis и запустил приложение. но этот запрос занимает более двух минут. поэтому я скопировал запрос в журнал и вставку локального разработчика. и запрос excute. но это занимает всего 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

EXPLAIN PLAN - ваш друг во всех случаях. Посмотрите на сканирование таблицы и отсутствующие индексы. Это очень сложный запрос с встроенной бизнес-логикой. – duffymo

+1

Выполнение запроса в sql-инструменте или его выполнение с помощью mybatis - это совсем другие вещи ... Запрос, вероятно, все еще так же быстро, но mybatis также создает объекты и замедляет работу. Таким образом, вы в основном сравниваете выполнение различных запросов и выполнение запроса + создание объекта. –

+0

извините .. просто исполняющий время. Я проверил время запроса запроса на сервере db. – Jongho

ответ

2

Я уже встречался с такой ситуацией: разница во времени не в выполнении запросов SQL, но по извлечению результатов.

Размер выборки по умолчанию для драйвера JDBC для Oracle JDBC равен 10, это означает, что ResultSet получает 10 строк по 10 строк, которые совершают много раундов в DB при наличии 1 миллиона записей. Размер Fetch должен быть увеличен.

С PostgreSql размер выборки по умолчанию не ограничен: в ResultSet подается весь результат (или до OutOfMemory). Может потребоваться уменьшить размер выборки.

Чтобы указать значение размер выборки в Mybatis:

Использование FetchSize атрибут в XML оператора выбора:

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

Или используйте FetchSize вариант в аннотации:

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

Значение в диапазоне 200-500 часто является хорошим компромиссом.