有粉丝好友问sharding-jdbc对分库分表的逻辑表数据分页排序是如何高效实现的?答案就是分表查询+流式归并。本文直接从MySQL JDBC的流式结果集来说明流式处理,时间宝贵,case如下:
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc_url","user","password");
StatementImpl stmt = (StatementImpl) conn.createStatement();
stmt.enableStreamingResults();
//Statement stmt = conn.createStatement();
//stmt.setFetchSize(Integer.MIN_VALUE);
TimeUnit.SECONDS.sleep(10);
ResultSet rs = stmt.executeQuery("select * from sys_user");
while(rs.next()){
}
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
StatementImpl.enableStreamingResults()方法可以开启流式结果集,也可以通过设置Statement..setFetchSize(Integer.MIN_VALUE)开启流式,具体逻辑代码参见源码:
protected boolean createStreamingResultSet() {
return ((this.query.getResultType() == Type.FORWARD_ONLY)
&& (this.resultSetConcurrency == java.sql.ResultSet.CONCUR_READ_ONLY)
&& (this.query.getResultFetchSize() == Integer.MIN_VALUE));
}
使用jvisualvm来对比下使用流式结果集(图1)和不使用流式结果集(图2)二者的内存占用情况:
图1
图2
本次测试数据量30w+,显然使用流式结果集时内存占用平稳开销小,不使用流式结果集时查询结果集会一次加载到内存,内存开销较大。