-
【系统版本 & kernel 版本】
centos 7.6 -
【TiDB 版本】
2.1.16 -
【集群节点分布】
pd节点:10.128.3.55/56/57
db节点:10.128.3.55/56/57
kv节点:10.128.3.55/56/57 -
【问题描述(我做了什么)】
周四将tidb从2.1.5升级到了2.1.16,bi人员反馈数据有问题,发现同样的SQL在MySQL5.7.18和tidb2.1.16上执行的结果不一致
SQL:
SELECT COUNT(*)
FROM users t1
LEFT JOIN shuttle_bus.sys_city t2 ON t1.city_id=t2.id AND t2.level=2
LEFT JOIN (SELECT user_id,MIN(CAST(pay_time AS DATE)) first_pay_time
FROM shuttle_bus.orders WHERE pay_status=‘1’ GROUP BY user_id
) t3 ON t1.id=t3.user_id
WHERE 1=1
AND t1.city_id=‘10024’
AND CAST(t1.ctime AS DATE)>=‘2019-07-29’
AND CAST(t1.ctime AS DATE)<‘2019-08-28’
MySQL上执行的结果为120条
tidb上执行的结果为19条
执行计划
请问 TiDB 和 MySQL 的这几个表 t1 t2 t3 的数据一样吗
是一样的,通过otter实时的从mysql同步到tidb
麻烦去 MySQL 和 TiDB 中分别查一下以下 SQL 比对下结果:
select count(*) from users t1 where t1.city_id=‘10024’ AND CAST(t1.ctime AS DATE)>=‘2019-07-29’ AND CAST(t1.ctime AS DATE)<‘2019-08-28’;
select count(*) from shuttle_bus.sys_city t2 where t2.level=2;
SELECT count(*) FROM shuttle_bus.orders WHERE pay_status=‘1’ GROUP BY user_id;
是一样的,结果分别是120,14,下面那条sql不加group by的结果是345828
方便提供一下表结构吗 如果可以的话: http://${tidb-server-ip}:${tidb-server-status-port}/stats/dump/${db_name}/${table_name} 把统计信息也导出来上传一下。
好的,表结构和统计信息我上传了,这个问题有点急,麻烦老师了!
我在测试环境装上了2.1.6版本,发现SQL执行结果和MySQL一致,可以确定是版本的问题啊!2.1.16可以回退到2.1.6吗?
稍等,我们研发同学正在确认。 目前没有通过标准方法回退,只能导出导入方式。 您把 2.1.6 的执行计划发一下
麻烦把 SQL 改一下: 将 “CAST(t1.ctime AS DATE)>=‘2019-07-29’ AND CAST(t1.ctime AS DATE)<‘2019-08-28’” 去掉 CAST 改成 “t1.ctime>=‘2019-07-29’ AND t1.ctime<‘2019-08-28’ ”
改好后跑一次,反馈给我结果
执行结果一致了
我们后续会修复这个问题,所以现在麻烦先用这个 SQL 。
老师,这是是什么原因呢?是因为多left join和cast有冲突还是仅仅是多left join的问题啊?
多谢老师,我们还有其他的多left join的SQL,现在还不能确定是否其他的SQL还有影响!
cast 让优化器误把 left join 转成了 inner join ,可以看看其他 left join 的 SQL 中有没有包含 cast 如果那些字段本来就是 date 类型的话,其实也不用使用 cast 转换格式了。
明白,谢谢老师!
此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。