0

我对“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 通过数据库进行矢量化。

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

4

2 回答 2

0

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

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

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

于 2021-10-15T13:39:17.240 回答
0

我不知道 DuckDB,所以我不能专门针对那个数据库系统回答。

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

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

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

于 2021-10-10T13:48:25.153 回答