Sharding-JDBC多表路由性能大bug?

本文深入分析了Sharding-JDBC在多表路由时存在的性能问题,通过研究源码发现由于去重操作导致了不必要的表查询。提出了改进方案,包括改造StandardShardingStrategy和StandardRoutingEngine,避免去重并保持数据与路由之间的对应关系,以提高查询效率。改造后的结果符合预期,减少了额外的表操作。
摘要由CSDN通过智能技术生成

一、发现问题

1、现象

配置说明:
		分两个库:ds0000、ds0001
        每个库两张表:t_user_0000、t_user_0001
        使用了StandardShardingStrategy 即标准分片策略
@Test
 public void select() {
   
     ArrayList<String> billCodes = new ArrayList<>();
     billCodes.add("447837049");
     billCodes.add("342287616");
     billCodes.add("1703389008");
     billCodes.add("577030235");
     billCodes.add("88678010");
     billCodes.add("102708391");
     
     Example example = new Example(User.class);
     example.createCriteria().andIn("id", billCodes);
     List<User> users = userMapper3.selectByExample(example);
 }

执行这样一次查询,in语句包含6个主键,实际这些数据只分布在两个库的两张表中。
但在实际执行中,sharding查询了4张表。

查询语句操作了无关表,这显然存在额外的性能消耗。

二、源码寻找答案

1、StandardRoutingEngine#route

最终,在StandardRoutingEngine#route 找到了线索

private Collection<DataNode> route(final TableRule tableRule, final List<RouteValue> databaseShardingValues, final List<RouteValue> tableShardingValues) {
   
	//本次查询需要路由到的dataSource
    Collection<String> routedDataSources = routeDataSources(tableRule, databaseShardingValues);
    Collection<DataNode> result = new LinkedList<>();
    //遍历dataSource,计算出需要查询的表
    for (String each : routedDataSources) {
   
    	//routeTables 返回的是最终需要执行的实际节点
        result.addAll(routeTables(tableRule, each, tableShardingValues));
    }
    return result;
}

请注意,route方法里遍历routedDataSources,对返回的DataNode节点集合进行了聚合。
这里感觉不对劲,为什么没有计算出准确的路由节点?继续看 StandardRoutingEngine#routeDataSources

private Collection<String> routeDataSources
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值