Има ли начин за интелигентно задаване на размера на извличане на JdbcTemplate?

Имам заявка, която връща отчети по период от време. Ако диапазонът от дати е голям, може да бъдат върнати 50 000 реда. Ако диапазонът от дати е много малък, могат да бъдат върнати 10 записа. Открих, че настройването на размера на извличане на 1000, когато се връщат 50k реда, значително ускорява времето за изпълнение. Но настройването му на 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 е отхвърлено от пролет 3.1 - по-добре използвайте JdbcDaoSupport или NamedParameterJdbcDaoSupport

Второ, в org.springframework.jdbc.core.support Class 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