Я использую Spring jdbcTemplate для выполнения запросов MySQL в моем приложении Java. Это моя функция:
public static ArrayList<Map<String, Object>> query(String q) throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
@SuppressWarnings("unchecked")
List<Map<String, Object>> result = jdbcTemplate.queryForList(q);
return (ArrayList<Map<String, Object>>) result;
}
В этом конкретном случае я передаю функции этот запрос:
"SELECT * FROM test WHERE name IN('string1', 'string2', 'string3', ...)";
В таблице test
всего 6 столбцов, строки в IN
варьируются от нескольких до 100 символов. jdbcTemplate.queryForList()
для выполнения запроса требуется 280 миллисекунд. ПРИМЕЧАНИЕ: для запуска jdbcTemplate.queryForList()
требуется 280 миллисекунд, а не для всей функции query
. Когда я запускаю точно такой же запрос на клиенте MySQL (HeidiSQL), это занимает всего 16 миллисекунд. ОБНОВЛЕНИЕ: Хайди поддерживает открытое соединение, так что это некорректное сравнение.
Вопрос: почему jdbcTemplate.queryForList()
так ужасно медленен по сравнению с тем же запросом, выполняемым на клиенте MySQL? Я использую его исключительно из соображений удобства, он может получить результат в ArrayList<Map<String, Object>>
, что мне и нужно. Могу ли я что-нибудь сделать, чтобы ускорить это, или мне просто бросить jdbcTemplate
все вместе и использовать что-нибудь еще?
ОБНОВЛЕНИЕ: Итак, я изменил свою функцию с jdbcTemplate на использование простого jdbc. Вот так выглядит эта мерзость. Это причина, по которой я в первую очередь выбрал jdbcTemplate. Теперь для выполнения того же запроса требуется 200 миллисекунд - небольшое улучшение, но все еще слишком медленно ...
public static ArrayList<Map<String,Object>> query(String Full_Command) {
try {
String URL = "jdbc:mysql://localhost/dbname";
String USER = "root";
String PASS = "";
java.sql.Connection Con = DriverManager.getConnection(URL, USER, PASS);
//create statement
Statement Stm = null;
//Stm = Con.createStatement();
Stm = (Statement) Con.createStatement();
//query
ResultSet Result = null;
boolean Returning_Rows = Stm.execute(Full_Command);
if (Returning_Rows) {
Result = Stm.getResultSet();
} else {
return new ArrayList<Map<String,Object>>();
}
//get metadata
ResultSetMetaData Meta = null;
Meta = Result.getMetaData();
//get column names
int Col_Count = Meta.getColumnCount();
ArrayList<String> Cols = new ArrayList<String>();
for (int Index=1; Index<=Col_Count; Index++) {
Cols.add(Meta.getColumnName(Index));
}
//fetch out rows
ArrayList<Map<String, Object>> Rows = new ArrayList<Map<String,Object>>();
while (Result.next()) {
HashMap<String,Object> Row = new HashMap<String,Object>();
for (String Col_Name:Cols) {
Object Val = Result.getObject(Col_Name);
Row.put(Col_Name,Val);
}
Rows.add(Row);
}
//close statement
Stm.close();
//pass back rows
return Rows;
} catch (Exception Ex) {
System.out.print(Ex.getMessage());
return new ArrayList<Map<String,Object>>();
}
}
ОБНОВЛЕНИЕ 2: я не разбивал функцию JDBC на время выполнения, и эта единственная строка является узким местом, каждый раз занимая ~ 190 миллисекунд:
java.sql.Connection Con = DriverManager.getConnection(URL, USER, PASS);
Любые комментарии?