Есть ли способ разумно установить размер выборки в JdbcTemplate?

У меня есть запрос, который возвращает отчеты по диапазону дат. Если диапазон дат большой, может быть возвращено 50 тыс. строк. Если диапазон дат очень мал, может быть возвращено 10 записей. Я обнаружил, что установка размера выборки на 1000, когда возвращается 50 тыс. строк, значительно ускоряет время выполнения. Но установка значения 1000 при возврате 10 строк замедляет работу и использует избыточную память. Это всего лишь один пример, у меня есть много запросов, которые возвращают несколько или много строк в зависимости от различных условий (тип выполняемого задания и т. д.).

В идеале было бы неплохо, если бы это можно было установить автоматически после выполнения запроса (но до возврата строк).

Есть лучший способ это сделать?

Я использую org.springframework.jdbc.core.support.JdbcDaoSupport.SimpleJdbcDaoSupport getJdbcTemplate().setFetchSize(1000);


person stilltrackin    schedule 22.08.2013    source источник


Ответы (3)


Это размер выборки по умолчанию. Очевидно, что лучшего значения не существует, поскольку, как вы описали, это компромисс между используемой памятью и круговым обходом базы данных (значение по умолчанию 100, кажется, работает достаточно хорошо для меня).

В любом случае вы можете установить размер выборки отдельно для каждого набора результатов с помощью ResultSet.setFetchSize().

person Vincent Malgrat    schedule 22.08.2013
comment
Другое дело, этот запрос может выполняться с сервера или с клиента. Правильная установка размера выборки имеет огромное значение, когда клиент удален (из-за количества переходов по сети). Но клиент также имеет ограниченную память.... - person stilltrackin; 22.08.2013

Во-первых, в документах говорится, что SimpleJdbcDaoSupport — это устарело начиная с Spring 3.1 - лучше использовать либо JdbcDaoSupport или NamedParameterJdbcDaoSupport

Во-вторых, в классе org.springframework.jdbc.core.support JdbcDaoSupport есть метод: applyStatementSettings(Statement stmt), который можно использовать для применения таких параметров оператора, как размер выборки, максимальное количество строк и время ожидания запроса.

Другим вариантом является ОГРАНИЧЕНИЕ числа или строк, возвращаемых в результирующем наборе в запросе (в MySQL используйте: LIMIT, для PL\SQL используйте "и rownum ‹ 50" - например)

person Nir Alfasi    schedule 22.08.2013

Я нашел решение. Я обнаружил, что размер выборки можно изменить в любой момент (даже при извлечении строк). В моей первой реализации размер выборки по умолчанию был равен 1. Когда я увидел вторую строку, я изменил ее на 10. Когда я увидел 11-ю строку, я изменил ее на 100 и т. д. Я провел несколько тестов производительности с использованием локальных и удаленных баз данных и приземлился. на следующем. (В Spring JDBC используются преобразователи строк. Вот как я реализовал org.springframework.jdbc.RowMapper).

public T mapRow(ResultSet rs, int index) {
    T dto = null;

    if (index == 0) {
        setFetchSize(rs, 50);
    } else if (index == 50) {
        setFetchSize(rs, 500);
    } else if (index == 1000) {
        setFetchSize(rs, 1000);
    }

    try {
        dto = mapRowToDto(rs, index);
    } catch (SQLException e) {
        throw new RuntimeException(e.getMessage(), e);
    }

    return dto;
}
person stilltrackin    schedule 23.08.2013