MySQL JDBC-запрос намного быстрее, чем должен быть в тесте JMH

0

В настоящее время я пытаюсь сравнить запросы MySQL с помощью JHM. Для этого я установил соединение, используя JDBC с докеризованным сервером.

Мой код:

@Benchmark
public void testWithPreparedStatement(Blackhole bh) throws SQLException {
    PreparedStatement st = connection.prepareStatement(query);
    st.setString(1, "Parameter1");
    st.setString(2, "Parameter2");
    bh.consume(st.executeQuery());
    connection.commit();
    st.close();
}

Вот результаты испытаний:

# Warmup Iteration   1: 2.318 ms/op
Iteration   1: 2.038 ms/op
Iteration   2: 1.972 ms/op
Iteration   3: 1.908 ms/op
Iteration   4: 2.000 ms/op
Iteration   5: 1.960 ms/op
Iteration   6: 1.939 ms/op
Iteration   7: 1.968 ms/op
Iteration   8: 1.959 ms/op

Запрос содержит несколько объединений, а база данных содержит данные, поэтому показатели не должны быть такими низкими.

Тот же запрос в DataGrip приводит к:

0 rows retrieved in 59ms (execution: 32ms, fetching: 27ms)

Что я пробовал:

  • Запуск RESET QUERY CACHE и FLUSH TABLES в методе @TearDown

  • Установка @TearDown на уровень. Level.Iteration

  • Установка autoCommit в false и вручную совершали запрос (см код) + установка TransactionLevel в READ_COMMITTED

Результаты, возвращаемые запросом с использованием JDBC, являются правильными, поэтому он выполняется правильно.

Есть идеи? Вся помощь приветствуется!

Теги:
database
jdbc
benchmarking
jmh

1 ответ

0

Кажется, что "проблема" была связана с использованием PreparedStatement, когда я переключился на обычный оператор Statement, я получил те же значения времени, что и в Datagrip.

Из этого SO-ответа я узнал, что PreparedStatement выполняет "Прекомпиляцию и кэширование на стороне DB оператора SQL", что, вероятно, приводит к более быстрому времени выполнения.

Итак, более медленный код, который я сейчас использую:

    @Benchmark
    public void testWithStatement(Blackhole bh) throws SQLException{
        Statement st = connection.createStatement();
        ResultSet rs = st.executeQuery(query);
        bh.consume(rs.next());
    }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню