Sharding-JDBC多表路由性能大bug?
一、发现问题
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