повышение скорости обработки запросов

0

имеет серьезные проблемы с моим временем обработки запроса:( Я думаю, это потому, что запрос получает перекомпилированное evrytime. но я не вижу никакого способа обойти это. следующий запрос/фрагмент кода:

private void readPerformance(String startTime, String endTime,
        String performanceTable, String interfaceInput) throws SQLException, IOException {
    String interfaceId, iDescp, iStatus = null;
    String dtime, ingress, egress, newLine, append, routerId= null;
    StringTokenizer st = null;
    stmtD = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,  
            java.sql.ResultSet.CONCUR_READ_ONLY);
    stmtD.setFetchSize(Integer.MIN_VALUE); 
    BufferedReader interfaceRead = new BufferedReader(new FileReader(interfaceInput));
    BufferedWriter pWrite = new BufferedWriter(new FileWriter("performanceInput.txt"));

    while((newLine = interfaceRead.readLine())!= null){
        st = new StringTokenizer(newLine,",");
        while(st.hasMoreTokens()){
            append = st.nextToken()+CSV+st.nextToken()+st.nextToken()+CSV+st.nextToken();
            System.out.println(append +" ");
            iStatus = st.nextToken().trim();
            interfaceId = st.nextToken().trim();
            append = append + CSV+iStatus+CSV+interfaceId;
            System.out.println(append +" ");
            pquery = " Select d.dtime,d.ifInOctets, d.ifOutOctets from "+performanceTable+"_1_60" +" AS d Where d.id = " +interfaceId 
            + " AND dtime BETWEEN " +startTime+ " AND "+ endTime;
            rsD = stmtD.executeQuery(pquery); 
            /* interface query*/
            while(rsD.next()){
                            dtime = rsD.getString(1);
                    ingress= rsD.getString(2);
                    egress = rsD.getString(3);
                    pWrite.write(append + CSV + dtime+CSV+ingress+CSV+egress+NL);

            }//end while
        }//end while
    }// end while

    pWrite.close();
    interfaceRead.close();
    rsD.close() ;   
    stmtD.close();

}

мое значение interfaceId продолжает меняться. поэтому я поставил запрос внутри цикла, что привело к повторной компиляции запроса несколько раз.

Есть ли какой-нибудь способ? Могу ли я судиться с хранимой процедурой в java? если да, то как? не знают об этом.

текущее время обработки составляет почти 60 минут (: (()!!! Получение текстового файла более 300 МБ Пожалуйста, помогите!!!

Спасибо.

  • 0
    Поразительна ирония неэффективной функции readPerformance.
Теги:
jdbc

3 ответа

1
Лучший ответ

Вы можете использовать PreparedStatement и параметры, которые могут избежать повторной компиляции запроса. Поскольку performanceTable является константой, это можно поместить в подготовленный запрос. Остальные переменные, используемые в условии WHERE, задаются как параметры.

Вне цикла создайте подготовленный оператор, а не обычный оператор:

   PreparedStatement stmtD = conn.prepareStatement(
         "Select d.dtime,d.ifInOctets, d.ifOutOctets from "+performanceTable+"_1_60 AS d"+ 
         " Where d.id = ? AND dtime BETWEEN ? AND ?");

Затем позже в вашем цикле задайте параметры:

   stmtD.setInteger(1, interfaceID);
   stmtD.setInteger(2, startTime);
   stmtD.setInteger(3, endTime);
   ResultSet rsD = stmtD.executeQuery();  // note no SQL passed in here

Возможно, неплохо также проверить план запросов из MySQL с помощью EXPLAIN, чтобы узнать, является ли это частью узкого места. Кроме того, в функции происходит довольно много конкатенации диагностических строк. После того, как запрос будет работать, удаление также может повысить производительность.

Наконец, обратите внимание, что даже если запрос выполняется быстро, сетевая латентность может замедлить работу. JDBC обеспечивает пакетное выполнение нескольких запросов, чтобы уменьшить общую латентность для каждого оператора. См. AddBatch/executeBatch при подключении.

  • 0
    попробовал, что ты сказал :) получил время простоя с 80 минут до 10 минут :). чувствую себя таким счастливым 10 все еще больше, но 80 слишком много: P
1

Требуется дополнительная информация, но я могу предложить некоторые общие вопросы/предложения. Это может не иметь ничего общего с компиляцией плана запроса (что было бы необычно)

  • Индексированы ли идентификаторы столбцов id и dtime?
  • Сколько раз запрос выполняется в течение 60 минут?
  • Сколько времени занимает каждый запрос?

Если время запроса велико, то проблема заключается в выполнении запроса, а не в компиляции. Проверьте индексы, как описано выше.

Если запросов много, тогда может возникнуть проблема с объемом запросов. Использование PreparedStatement (см. Ответ mdma) может помочь. Или вы можете попробовать и пакетные идентификаторы интерфейса, которые вы хотите, используя оператор "in" и выполняющий запрос для каждых 100 идентификаторов интерфейса, а не один для каждого.

EDIT: В качестве хорошей практики вы должны ВСЕГДА использовать PreparedStatement, поскольку он будет правильно обрабатывать типы данных, такие как даты, поэтому вам не нужно беспокоиться о форматировании их в правильный синтаксис SQL. Также предотвращает SQL-инъекцию.

0

Из взглядов вещей вы начинаете несколько запросов (даже 100 на основе размера вашего файла) Вместо этого из вашего входного файла создайте список с разделителями-запятыми всех значений interfaceId, а затем сделайте 1 вызов SQL с помощью ключевого слова "IN". Вы знаете, что переменные performanceTable, startTime и endTime меняются, поэтому запрос будет выглядеть примерно так.

SELECT d.dtime,d.ifInOctets, d.ifOutOctets 
FROM MyTable_1_60 as d 
WHERE dtime BETWEEN '08/14/2010' AND '08/15/2010'
AND d.id IN ( 10, 18, 25, 13, 75 ) 

Затем вы можете открыть файл, сбросить результирующий набор одним махом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню