Я использую Sybase, и у меня был некоторый код, который выглядел так:
String[] ids = ... an array containing 80-90k strings, which is retrieved from another table and varies.
for (String id : ids) {
// wrap every id with single-quotes
}
String idsAsString = String.join(",", ids);
String query = String.format("select * from someTable where idName in (%s)", idsAsString);
getNamedParameterJDBCTemplate().query(query, resultSetExtractor ->{
// do stuff with results
});
Я рассчитал, сколько времени потребовалось, чтобы добраться до внутреннего тела resultSetExtractor, и это никогда не занимало больше 4секунд.
Но чтобы защитить код, я попытался пройти маршрут переменной связывания. Таким образом, этот код выглядел следующим образом:
String[] ids = ... an array containing 80-90k strings, which is retrieved from another table and varies.
String query = "select * from someTable where idName in (:ids)";
Map<String, Object> params = new HashMap<>();
params.put("ids", Arrays.asList(ids));
getNamedParameterJDBCTemplate().query(query, params, resultSetExtractor ->{
// do stuff with results
});
Но выполнение этого способа займет до 4-5 минут, чтобы окончательно выдать следующее исключение:
21-10-2019 14:04:01 DEBUG DefaultConnectionTester:126 - Testing a Connection in response to an Exception:
com.sybase.jdbc4.jdbc.SybSQLException: The token datastream length was not correct. This is an internal protocol error.
Я такжеу меня есть другие фрагменты кода, в которых я передаю массивы размером 1-10 в качестве переменных связывания и заметил, что эти запросы превратились из мгновенных в занимающие до 10 секунд.
Я удивлен, делая это способом переменных связыванияэто совсем другое, не говоря уже о , что резко отличается. Может кто-нибудь объяснить, что здесь происходит? Эта переменная связывания делает что-то другое под капотом, в отличие от отправки отформатированной строки через JDBC? Есть ли другой способ обезопасить мой код без резкого снижения производительности?