sharding-jdbc查询结果合并有问题

版本:sharding-jdbc 4.1.1
对接数据库类型:MySQL,版本5.7
配置:单库分表


原生SQL如下:
SELECT userId, sum( order_money ) orderMoeny, FROM user_order uo WHERE uo.source = 16 AND uo.create_time >= ‘2021-11-29 00:00:00’
AND uo.create_time <= ‘2021-12-05 23:59:59’
GROUP BY
uo.user_id
ORDER BY
orderMoeny DESC
LIMIT 20

经过解析之后变成了如下两段SQL:
SELECT userId, sum( order_money ) orderMoeny, FROM user_order_202111 uo WHERE uo.source = 16 AND uo.create_time >= ‘2021-11-29 00:00:00’
AND uo.create_time <= ‘2021-12-05 23:59:59’
GROUP BY
uo.user_id
ORDER BY
orderMoeny DESC
LIMIT 2147483647
SELECT userId, sum( order_money ) orderMoeny, FROM user_order_202112 uo WHERE uo.source = 16 AND uo.create_time >= ‘2021-11-29 00:00:00’
AND uo.create_time <= ‘2021-12-05 23:59:59’
GROUP BY
uo.user_id
ORDER BY
orderMoeny DESC
LIMIT 2147483647
我去数据库分别执行了两段SQL,证明了只返回了第一段SQL的返回结果,第二段SQL的结果没有进行合并。想请大家帮忙看看是我哪里配置有问题吗

1 个赞

不知道 5.0.0 是否有这个问题,我会尝试一下。

@adam 你好,我使用类似的配置试了下分组聚合,没有复现你反馈的问题。

配置:

shardingRule:
  tables:
    t_order:
#      actualDataNodes: ds_${0..1}.t_order_${0..1}
      actualDataNodes: ds_0.t_order_${0..1}
      tableStrategy:
        inline:
          shardingColumn: order_id
          algorithmExpression: t_order_${order_id % 2}
    t_order_item:
      actualDataNodes: ds_${0..1}.t_order_item_${0..1}
      tableStrategy:
        inline:
          shardingColumn: order_id
          algorithmExpression: t_order_item_${order_id % 2}
      keyGenerator:
        type: SNOWFLAKE
        column: order_item_id
  bindingTables:
    - t_order,t_order_item
  defaultDatabaseStrategy:
    none:
  defaultTableStrategy:
    none:

分组聚合结果如下:

mysql> select * from t_order where order_id in (2, 4, 6, 7, 8, 9);
+----------+---------+---------+---------------+-------------+-------------+
| order_id | user_id | content | business_data | create_time | order_money |
+----------+---------+---------+---------------+-------------+-------------+
|        2 |       2 | 22      | NULL          | 2021-11-01  |           1 |
|        4 |       4 | 44      | NULL          | 2021-11-02  |           3 |
|        6 |       6 | 6666    | NULL          | NULL        |          17 |
|        8 |       8 | 88888   | NULL          | NULL        |          11 |
|        7 |       6 | 77777   | NULL          | NULL        |          13 |
|        9 |       8 | 88888   | NULL          | NULL        |           7 |
+----------+---------+---------+---------------+-------------+-------------+
6 rows in set (0.01 sec)

mysql> select user_id, sum(order_money) orderMoeny from t_order where order_id in (2, 4, 6, 7, 8, 9) group by user_id order by orderMoeny ;
+---------+------------+
| user_id | orderMoeny |
+---------+------------+
|       2 |          1 |
|       4 |          3 |
|       8 |         18 |
|       6 |         30 |
+---------+------------+
4 rows in set (0.01 sec)

路由结果如下:

[INFO ] 11:50:18.955 [pool-2-thread-1] ShardingSphere-SQL - Actual SQL: ds_0 ::: select user_id, sum(order_money) orderMoeny from t_order_0 where order_id in (2, 4, 6, 7, 8, 9) group by user_id order by orderMoeny
[INFO ] 11:50:18.955 [pool-2-thread-1] ShardingSphere-SQL - Actual SQL: ds_0 ::: select user_id, sum(order_money) orderMoeny from t_order_1 where order_id in (2, 4, 6, 7, 8, 9) group by user_id order by orderMoeny

如果方便的话,可否提供一个能够复现问题的 demo?

@adam
我用 5.0.0 版本验证了 分表&范围查询 的场景,结果是正常的。

配置:

rules:
- !SHARDING
  tables:
    t_order:
      actualDataNodes: ds.t_order_${0..1}
      tableStrategy:
        standard:
          shardingColumn: order_id
          shardingAlgorithmName: t_order_inline
      keyGenerateStrategy:
        column: order_id
        keyGeneratorName: snowflake
        
  shardingAlgorithms:
    t_order_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_${order_id % 2}
        allow-range-query-with-inline-sharding: true
        
  keyGenerators:
    snowflake:
      type: SNOWFLAKE
      props:
        worker-id: 123

数据平均分布于两张表

t_order_0:
image

t_order_1:
image

全量查询:

mysql> select * from t_order order by order_id;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
|        1 |       1 | 1      |
|        2 |       2 | 2      |
|        3 |       3 | 3      |
|        4 |       4 | 4      |
|        5 |       5 | 5      |
|        6 |       6 | 6      |
|        7 |       7 | 7      |
|        8 |       7 | 8      |
+----------+---------+--------+
8 rows in set (0.01 sec)

范围查询:

mysql> select * from t_order where order_id >= 2 and order_id <= 7 order by order_id;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
|        2 |       2 | 2      |
|        3 |       3 | 3      |
|        4 |       4 | 4      |
|        5 |       5 | 5      |
|        6 |       6 | 6      |
|        7 |       7 | 7      |
+----------+---------+--------+
6 rows in set (0.02 sec)

很奇怪,我同样的代码,在不同的分支,执行的结果,完全不一样

那么,问题解决了吗?

没有,我试了一下,你们测试的数据量不多,数据量多一点,并且只筛选前3条数据试一下

测试了还是没有发现问题,请问你的数据量是有多大?

单表的数据量201111这张表的数据量在三百多万

@adam 我这边对接了一个线上系统,使用 ShardingSphere 4.1.0,单表数据量有千万和亿级的,范围查询合并也没有类似的问题。
请你提供一个可以重现问题的 demo 项目吧。

我这边想用demo试一下但也复现不出来,但我生产库上就是有问题。。。 这个就尴尬了

要不我电脑直接给你远程看看 这个问题我真的要疯了

包括我的代码,如果是用测试库都没问题,到生产库不行了

考虑检查下测试和生产环境依赖的包是否有差异,另外,生产可以断点调试吗? 观察一下 merge 之前的结果是否符合预期?

测试环境现在也是合并有问题了,问个比较尴尬的问题,断点该打到哪个地方比较合适

ShardingSphereStatement 或 ShardingSpherePreparedStatement
executeQuery() 方法


执行的这个方法,并且我断点打到这里,确实只执行了一次

嗯,调试看是哪里导致的问题吧,这个要靠你自己完成啦 :grinning:

京ICP备2021015875号