从SQL查询中度量ResultSet的时间性能



我对"ResultSet"的理解有一些问题。如果我想测量执行查询所需的性能时间,是否需要遍历Resultset——>而(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通过数据库进行矢量化。

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

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

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

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

我不知道DuckDB,所以我不能具体回答这个数据库系统。

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

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

简而言之,给定的行为是不同的,唯一确定的方法是在所有行的执行和提取中测量它。