【问题标题】:Measure time performance of ResultSet from SQL queries从 SQL 查询中测量 ResultSet 的时间性能
【发布时间】:2021-10-08 14:26:19
【问题描述】:

我对“ResultSet”的理解有些问题。如果我想测量执行查询所需的性能时间,我是否需要遍历Resultset --> while(rs.next()),因为实际结果集已经包含了所有结果?还是更像是一个缓冲区,在迭代 ResultSet 时会生成一些元组?

Statement b = conn.createStatement();
ResultSet rs2 = b.executeQuery("Select o_orderkey, o_orderstatus, o_orderdate, o_orderpriority, o_comment from orders");
while(rs2.next()){
    int okey=rs2.getInt(1);
    String st=rs2.getString(2);
    Date dt=rs2.getDate(3);
    String pr=rs2.getString(4);
    String co=rs2.getString(5);
}
long endTime = System.currentTimeMillis();
System.out.println(i+". DuckDB " + (endTime- startTime) +" ms");

对于此示例,性能存在巨大差异。当我只测量它需要在没有 while 循环的情况下构建 ResultSet 的时间时,它只是时间的一小部分。这就是为什么我认为它可能依赖于数据库,因为 DuckDB 通过数据库进行矢量化。

我现在的问题是哪种方式是正确的,而我只想有时间回答问题?

【问题讨论】:

  • 我相信,在后台,JDBC 将打开一个数据库游标,然后在您处理它时迭代结果集。
  • 好的,这意味着您认为实际上需要滚动浏览 ResulSet。我没听错吗?
  • 或多或少,是的,整个结果集不会立即进入 Java。

标签: sql jdbc resultset duckdb


【解决方案1】:

我不了解 DuckDB,因此无法专门针对该数据库系统回答。

一般来说,这个问题没有简单的答案。一些 JDBC 驱动程序会在您执行查询时获取所有行,然后才返回结果集,而其他一些 JDBC 驱动程序只会在您遍历结果集时获取行。 JDBC 驱动程序可以批处理行,因此可以从单个批处理中满足对next() 的多次调用,并且仅在批处理(几乎)为空时往返于服务器,或者它们可以为每次调用往返于数据库到next()。理论上,每个getXXX 甚至有可能往返于数据库(尽管这种情况并不常见,或者仅适用于 blob)。

换句话说,数据库系统及其驱动程序之间的行为会有所不同,并且还可能取决于您是否处于自动提交模式、使用可更新或可滚动的结果集,以及可能的其他因素(配置驱动程序、数据库系统版本等)。

简而言之,给定的行为会有所不同,唯一可靠的方法是在所有行的执行和获取中对其进行衡量。

【讨论】:

    【解决方案2】:

    DuckDB 使用矢量化执行引擎,允许流式查询处理。如果您没有完全具体化的查询结果,这意味着每次执行 next() 时,您都会获得下一批结果(即,您将对表的下 1024 个元素执行查询计划)。

    除此之外,生成 java 数据集还需要一些转换成本,因为您必须进行类型转换。

    如果你想做一个 java 基准测试,我会说完全消耗批处理结果是可行的方法,只要你对要比较的其他系统做同样的事情:-)

    【讨论】:

      猜你喜欢
      • 2018-07-25
      • 2011-10-14
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      • 2019-01-27
      • 2014-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多