2013-04-05 3 views
4

У меня есть Java-программа, которая должна итерации через HashMap получить параметры, которые затем используются для запроса базы данных MySQL. Код выглядит следующим образом:Выполнение одного и того же запроса запроса несколько раз с различными параметрами: Mysql

Iterator<Entry<String, Double>>it = ws.entrySet().iterator(); 
Connection con = null; 

while(it.hasNext()) 
{ 
    Entry<String, Double>pairs = it.next(); 
    PreparedStatement ps = con.prepareStatement("select doc_freq from lookup where word=?"); 
    ps.setString(1, pairs.getKey()); 
    ResultSet rs = ps.executeQuery(); 
} 

Процесс неоднократно обращается к базе данных для каждой итерации цикла (которая составляет около 500 раз) замедляет мое приложение. Есть ли способ отправить все эти параметры сразу, чтобы я мог получить доступ к базе данных только один раз?

+0

Вы можете создать временную таблицу и сохраните 'pairs.getKey()' значения внутри него, а затем использовать оператор 'JOIN' должен оповестить вашу таблицу и вашу временную таблицу для извлечения данных. Конечно, не забудьте удалить временную таблицу, когда закончите ее использовать (на всякий случай RDBMS не справится с этим для вас). –

+0

Является ли запрос медленным? Где ваш цикл обработки проводит большую часть времени? – dcernahoschi

+1

Прочитайте это: [Batching Select Statement в JDBC] (http://www.javaranch.com/journal/200510/Journal200510.jsp#a2) – informatik01

ответ

1

Учитывая СЗ карту, вы можете сделать один запрос таким образом:

Connection con = getConnection(); 
Set<String> ks = ws.keySet(); 

if (ks.size() > 0) { 
    StringBuilder inStatement = new StringBuilder("?"); 
    for (int i = 1; i < ks.size(); i++) { 
     inStatement.append(", ?"); 
    } 

    PreparedStatement ps = con.prepareStatement("select doc_freq from lookup where word in (" + inStatement.toString() + ")"); 

    int k = 1; 
    for (String key : keySet) { 
     ps.setString(k++, key); 
    } 
    ResultSet rs = ps.executeQuery(); 
} 
+0

RDBMS имеют медленную производительность по таким запросам. Всегда лучше использовать 'id =? или id =? 'конкатенация. Тем не менее, 'JOIN' намного лучше, чем все эти альтернативы. –

+0

Не 'id =? или id =? 'и' id в (?,?) 'эквивалент? Во всяком случае, я не вижу, как будет помогать соединение ... – blint

+0

Нет, это не так. –

0

Подготовьте инструкцию один раз, затем выполните итерацию и установите для нее параметр, а затем выполните. Это из Javadoc

SQL-оператор с или без параметров, может быть предварительно скомпилированных и хранится в PreparedStatement объекта. Затем этот объект можно использовать для эффективного выполнения этого утверждения несколько раз. Этот метод оптимизирован для обработки параметрических операторов SQL, которые выигрывают от предварительной компиляции. Если драйвер поддерживает прекомпиляцию ...

Iterator<Entry<String, Double>>it = ws.entrySet().iterator(); 
Connection con = getConnection(); 

PreparedStatement ps = con.prepareStatement("select doc_freq from lookup where word=?"); 
while(it.hasNext()) 
{ 
    Entry<String, Double>pairs = it.next(); 
    ps.setString(1, pairs.getKey()); 
    ResultSet rs = ps.executeQuery(); 
} 

Хорошо, я объясню это. Когда запрос компилируется в db, он ускоряет выполнение и получение результатов один за другим, это то же самое, что и выполнение одного запроса с несколькими параметрами. производительность равна. Но если вы подготовите, скомпилируете один и тот же SQL-запрос несколькими типами, db создаст план выполнения каждый раз, когда вы скомпилируете запрос, это наступление времени. Вот почему этот метод называется эффективным в документах. Этот термин также известен как план объяснения, и он создан db для лучшей оптимизации запроса.

+0

Я протестировал это, и это не ускорит время процесса. –

+0

@LuiggiMendoza Это сохранит время компиляции. –

+0

yes Я пробовал это, но, похоже, не улучшил время процесса. – jayanth

0

Непонятно, почему это медленно, но одной обычной проблемой являются накладные расходы каждой транзакции.

Вы можете установить innodb_flush_log_at_trx_commit в 0 или 2, и все будет быстрее. Будьте осторожны, хотя значение по умолчанию 1 является единственным ACID-совместимым параметром. Для большинства настроек 2 это отличное значение.

set global innodb_flush_log_at_trx_commit = 2; 
Смежные вопросы