【问题标题】:MySQL JDBC query much faster than it should be in JMH testMySQL JDBC 查询比 JMH 测试中的查询要快得多
【发布时间】:2019-02-05 21:15:42
【问题描述】:

我目前正在尝试使用 JHM 对 MySQL 查询进行基准测试。为此,我使用 JDBC 与 dockerized 服务器建立了连接。

我的代码:

@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)

我尝试过的:

  • @TearDown方法中运行RESET QUERY CACHEFLUSH TABLES

  • @TearDown 设置为Level.Iteration

  • autoCommit 设置为false 并手动提交查询(参见:代码)+ 将TransactionLevel 设置为READ_COMMITTED

使用 JDBC 的查询返回的结果是正确的,因此它被正确执行。

有什么想法吗?感谢所有帮助!

【问题讨论】:

    标签: java mysql jdbc benchmarking jmh


    【解决方案1】:

    “问题”似乎与使用 PreparedStatement 有关,一旦我切换到正常的 Statement,我得到的时间值与在 Datagrip 中得到的值相同。

    this SO answer 我发现PreparedStatement 执行“SQL 语句的预编译和数据库端缓存”,这可能会导致更快的执行时间。

    所以我现在使用的代码比较慢:

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

    【讨论】:

      猜你喜欢
      • 2011-09-20
      • 2016-06-23
      • 2010-11-17
      • 2021-11-13
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 2018-01-04
      • 2012-06-29
      相关资源
      最近更新 更多