Сравнительные данные о весне и JDBI в выбранной базе данных postgres - PullRequest
0 голосов
/ 02 мая 2020

Я хотел сравнить производительность данных Spring с JDBI. Я использовал следующие версии

Spring Boot 2.2.4.RELEASE

против

JDBI 3.13.0

. Тест довольно прост, выберите * из таблицы администратора и конвертируйте. к списку объектов администратора

приведены соответствующие данные

с пружинной загрузкой

public interface AdminService extends JpaRepository<Admin, Integer> {


}

и для JDBI

public List<Admin> getAdmins() {
    String sql = "Select admin_id as adminId, username from admins";
    Handle handle = null;
    try {
        handle = Sql2oConnection.getInstance().getJdbi().open();
        return handle.createQuery(sql).mapToBean(Admin.class).list();
    }catch(Exception ex) {
        log.error("Could not select admins from admins: {}", ex.getMessage(), ex );
        return null;
    } finally {
        handle.close();
    }
}

тестовый класс выполняется с использованием junit 5

@Test
@DisplayName("How long does it take to run 1000 queries")
public void loadAdminTable() {
    System.out.println("Running load test");
    Instant start = Instant.now();
    for(int  i= 0;i<1000;i++) {
        adminService.getAdmins(); // for spring its findAll()
    for(Admin admin: admins) {
                if(admin.getAdminId() == 654) {
                    System.out.println("just to simulate work with the data");
                }
            }
    }
    Instant end = Instant.now();
    Duration duration = Duration.between(start, end);
    System.out.println("Total duration: " + duration.getSeconds());

}

Я был шокирован, получив следующие результаты

Spring Data: 2 секунды JDBI: 59 секунд

любая идея, почему я получил эти Результаты? я ожидал, что JDBI будет быстрее

Ответы [ 2 ]

0 голосов
/ 03 мая 2020

Проблема заключалась в том, что Spring управляет жизненным циклом соединения для нас и по уважительной причине после прочтения документов JDBI

Производительность снижается при каждом выделении и освобождении соединения. В приведенном выше примере две операции insertFullContact принимают отдельные объекты Connection из пула соединений с базой данных.

я изменил код теста JDBI на следующий

@ Test @DisplayName («Сколько времени требуется для выполнения 1000 запросов») publi c void loadAdminTable () {System.out.println («Проверка работающей нагрузки»); String sql = "Выберите admin_id как adminId, имя пользователя из списка администраторов"; Дескриптор handle = null; handle = Sql2oConnection.getInstance (). getJdbi (). open (); Мгновенный запуск = Instant.now (); for (int i = 0; i <1000; i ++) {</p>

    List<Admin> admins = handle.createQuery(sql).mapToBean(Admin.class).list();
    if(!admins.isEmpty()) {
        for(Admin admin: admins) {
            System.out.println(admin.getUsername());
        }
    }
}
handle.close();
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("Total duration: " + duration.getSeconds());

}

таким образом, соединение открывается один раз, и запрос выполняется 1000 раз

окончательный результат составил 1 секунду

в два раза быстрее, чем весна

0 голосов
/ 02 мая 2020

С одной стороны, вы, кажется, совершаете некоторые базовые c ошибки сравнительного анализа:

  • Вы не прогреваете JVM.
  • Вы не используете результаты в В любом случае.

Поэтому то, что вы видите, может быть просто следствием различных оптимизаций виртуальной машины. Изучите JMH , чтобы улучшить свои тесты.

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

Предполагая, что ваши результаты реальны, следующий шаг - выяснить, на что тратится дополнительное время. Я ожидаю, что наибольшее время будет потрачено на выполнение операторов SQL и получение результата по сети. Поэтому вам следует проверить, какие операторы SQL действительно выполняются.

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

...