欢迎光临
我们一直在努力

7. sharding-jdbc源码之group by结果合并(2)

通过6. sharding-jdbc源码之group by结果合并(1)的分析可知,如果要走GroupByMemoryResultSetMerger,那么需要这样的SQL:SELECT o.status, count(o.user_id) count_user_id FROM t_order o where o.user_id=10 group by o.status order by count_user_id asc,即group by和order by的字段不一样;接下来的分析都是基于这条SQL;

ExecutorEngine.build()方法中通过return new GroupByMemoryResultSetMerger(columnLabelIndexMap, resultSets, selectStatement);调用GroupByMemoryResultSetMerger,GroupByMemoryResultSetMerger的构造方法源码如下:

7. sharding-jdbc源码之group by结果合并(2)

 

在实际表t_order_0和t_order_1上执行SQL返回的结果如下:

7. sharding-jdbc源码之group by结果合并(2)

t_order_0和t_order_1结果.png

知道实际表的返回结果后,后面的分析更容易理解;假定这些返回结果用json表示为:{[{"status":"NEW", "count_user_id":1},{"status":"VALID", "count_user_id":1},{"status":INIT, "count_user_id":2}],[{"status":"VALID", "count_user_id":1},{"status":"INIT", "count_user_id":1},{"status":""NEW, "count_user_id":3}]}

init()方法源码如下:

7. sharding-jdbc源码之group by结果合并(2)

 

initForFirstGroupByValue()源码如下:

7. sharding-jdbc源码之group by结果合并(2)

 

该方法都是为了接下来的聚合计算做准备工作;

aggregate()源码如下–即在内存中将多个实际表中返回的结果进行聚合:

7. sharding-jdbc源码之group by结果合并(2)

 

经过for (ResultSet each : resultSets) { while (each.next()) { … 遍历所有结果并聚合计算后,aggregationMap这个map中已经聚合计算完后的结果,如下所示:

7. sharding-jdbc源码之group by结果合并(2)

 

再将aggregationMap中的结果封装到Map<GroupByValue, MemoryResultSetRow> dataMap这个map中,结果形式如下所示:

{
 "VALID": ["VALID", 2],
 "INIT": ["INIT", 5],
 "NEW": ["NEW", 3]
}

MemoryResultSetRow的本质就是一个Object[] data,所以其值是["VALID", 2],["INIT", 5]这种形式

将结果转成List<MemoryResultSetRow>,并且排序–如果有order by,那么根据order by的值进行排序,否则根据group by的值排序:

private List<MemoryResultSetRow> getMemoryResultSetRows(final Map<GroupByValue, MemoryResultSetRow> dataMap) {
 List<MemoryResultSetRow> result = new ArrayList<>(dataMap.values());
 Collections.sort(result, new GroupByRowComparator(selectStatement));
 return result;
}

7. sharding-jdbc源码之group by结果合并(2)

 

到这里,GroupByMemoryResultSetMerger即内存GROUP聚合计算已经分析完成,依旧通过运行过程图解加深对GroupByMemoryResultSetMerger的理解,运行过程图如下图所示:

7. sharding-jdbc源码之group by结果合并(2)

 

7. sharding-jdbc源码之group by结果合并(2)

 

总结

正如GroupByMemoryResultSetMerger的名字一样,其实现原理是把所有结果加载到内存中,在内存中进行计算,而GroupByMemoryResultSetMerger是流式计算方法,并不需要加载所有实际表返回的结果到内存中。这样的话,如果SQL返回的总结果数比较多,GroupByMemoryResultSetMerger的处理方式就可能会撑爆内存;这个是使用sharding-jdbc一个非常需要注意的地方;

 收藏 (0) 打赏

您可以选择一种方式赞助本站

支付宝扫一扫赞助

微信钱包扫描赞助

未经允许不得转载:英协网 » 7. sharding-jdbc源码之group by结果合并(2)

分享到: 生成海报
avatar

热门文章

  • 评论 抢沙发

    • QQ号
    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址

    登录

    忘记密码 ?

    切换登录

    注册

    我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活