Как ускорить запросы в БД JDBC

206
04 мая 2018, 13:42

Имеется 2 мапы, в одной 120 элементов, в другой 40. Идет перебор, то есть сначала перебираются все элементы мапы 2 с первым элементом первой мапы, все это обращается в БД. Элемент первой мапы + элементы по очереди второй мапы(например: 123456, 456123; 123456, 789654 и тд).

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

@Service
public class GetDistanceBetweenStationsImpl extends ConnectionDB implements GetDistanceBetweenStations {
// Подключаем логгер
private static Logger logger = LoggerFactory.getLogger(GetDistanceBetweenStationsImpl.class);
private GetDistanceBetweenStationsImpl() {
}
@Override
public List<Integer> getDistanceBetweenStations(String keyOfStationDeparture, String keyOfStationDestination) {
    ResultSet resultSet;
    CallableStatement callableStatement = null;
    List<Integer> listResult = new ArrayList<>();
    try (Connection connection = getDataSource().getConnection()) {
        // Подготавливаем запрос
        callableStatement = connection.prepareCall(" { call getdistancetest(?,?) } ");
        // Определяем значения параметров
        callableStatement.setString(1, keyOfStationDeparture);
        callableStatement.setString(2, keyOfStationDestination);
        // Выполняем запрос
        resultSet = callableStatement.executeQuery();
        // Вычитываем полученное значение
        while (resultSet.next()) {
            listResult.add(resultSet.getInt(1));
        }
        logger.debug("Get distance for: {}", keyOfStationDeparture + "_" + keyOfStationDestination + ": " + listResult.get(0));
    } catch (SQLException sqlEx) {
        logger.error("Ошибка запроса {} - {}", callableStatement, sqlEx.getMessage());
    }
    return listResult;
}
}

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

Вот сам код перебора и вызова запроса, тут у меня есть проверка, если данное сочетание уже было, то я в БД не лезу

Iterator<Map.Entry<Integer, Route>> iterator = mapOfRoutes.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry<Integer, Route> entry = iterator.next();
        for (int i = 0; i < listOfWagons.size(); i++) {
            String stationCode1 = listOfWagons.get(i).getKeyOfStationDestination();
            String stationCode2 = entry.getValue().getKeyOfStationDeparture();
            String key = stationCode1 + "_" + stationCode2;
            // Заполняем мапы расстояний
            if (!rootMapWithDistanceMoreMaxDist.containsKey(key)) {
                if (!rootMapWithDistances.containsKey(key)) {
                    List<Integer> listDistance = getDistanceBetweenStations.getDistanceBetweenStations(stationCode1, stationCode2);
                    int distance = listDistance.get(0);
                    if (distance == -1) {
                        logger.error("Проверьте код станции {}");
                        }
                    } else {
                        if (distance != -20000) {
                            rootMapWithDistances.put(key, listDistance);
                        } else {
                            rootMapWithDistanceMoreMaxDist.put(key, listDistance);
                        }
                    }
                }
            }
        }
    }

У меня проблема в том, что при маленьком объеме элементов в мапе, например 60 в первой и 30 во второй, и в зависимости от повторок, все это конечно работает быстро, около 15 секунд.

Но когда я сделал 120 элементов в первой и 40 во второй, уменьшил количество повторенных элементов в файле, откуда все гружу, то у меня сейчас все это дело работает минуту 45 секунд. И я никак не могу уменьшить это время, я уже половину вынес из запроса, оставил только коды станций, и все равно.

Подскажите, пожалуйста, как можно ускорить мое обращение к БД, ну не может же быть так, что 3500 запросов так долго работают, я видел как 30 000 запросов за 30 секунд отрабатывают.

Соединение создаю через org.apache.tomcat.jdbc.pool.DataSource

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" lazy-init="false"  destroy-method="close">
    <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="url" value="строка к БД"/>
    <property name="username" value="логин"/>
    <property name="password" value="пароль"/>
</bean>

База данный Postgres. Подскажите, пожалуйста, как оптимизировать мне обращение, может какие-то пулы создать? В интернете перепробовал способы, которые предлагались, не помогли мне.

READ ALSO
Управление проектом

Управление проектом

Занимался тем, что временно исключал из проекта некоторые файлы, случайно ткнул в пункт Generated Sources Root, теперь не могу эту задачу скомпилироватьКак...

168
Ошибка при передачи файла BufferOverflowException

Ошибка при передачи файла BufferOverflowException

Собественно вопрос указан в заголовкеПередаю файл частями в канал, появляеться -> BufferOverflowException

209
Проблема с получением конфигурации Realm в Android

Проблема с получением конфигурации Realm в Android

Когда питаюсь что то записать в Realm вылетает ошибкаДелал все по туториале

161
Не загружает fxml файл

Не загружает fxml файл

Написал мини проект на java протестировал в intellijIDEAВсё работает

243