查询条件使用now()函数,相同sql代码执行结果与数据库执行结果不一致

我试试看

测试环境的应用重启频率还是很高的,而且如果是事务问题那我即使入参固定的日期还是使用now()函数应该都无法解决问题,但实际上看起来问题是出在now()函数的解析上


前面的贴图中展示的就是dashborad打出的代码执行sql的执行计划和我直接在数据库中执行sql的执行计划的对比

用附件文本形式
1、返回1000行的SQL文本与执行计划
。。。
2、返回5000行的SQL文本与执行计划
。。。

1、1000+的SQL的执行计划


2、5000+的SQL的执行计划

Mybatis好像不支持这种指定变量,使用这个方式一条数据都无法查出来了

TIMESTAMPDIFF返回的数据类型是整型,mybatis传参使用的是字符型,会不会是隐式类型转换引起的
MySQL :: MySQL 8.0 Reference Manual :: 12.7 Date and Time Functions

我试试如果我将now()的结果转换为字符串,再执行结果是否会有差异,如果没差异的话就可以说明是mybaits执行TIMESTAMPDIFF里面参数的类型问题了

:expressionless:让大佬看吧,图片看不明白


将SQL中的now()函数强行进行类型转换成字符串后,结果就正确了,看来确实与mybatis的类型转换有关

1 个赞

是还缺少了什么信息吗?图片中的执行计划就是把普通直接执行出来的执行计划图形化了一下,里面的信息都是全的

可不可以先执行下select now();然后把这个结果赋值到sql里

不容易啊。看来这种要显式转换

目前的测试结果发现原因是mybatis在执行timstampdiff函数时对里面的参数进行了类型转换,只有参数为字符串时结果才是准确的,如果参数中涉及date类型的话要注意了。。。

今天再挖挖到底是怎么进行的转换,最终又为何会导致一部分数据查不出来。 :innocent:

不太科学哎,它只是负责下发sql,now()函数下发到数据库以后才会有值,他怎么会转换呢

也有道理,排除是mybatis解析下发出的问题,同样都是在TIDB中执行,那他的原始sql实际都是一样的,怎么会结果不同呢,并且从dashboard上面拉出的执行计划能够看出,执行的两个子步骤筛选的数据是一样多的,但是聚合在一起就少了,不太能理解。
尝试过在代码中打印出sql执行now()的值,全都是正常的。

提个建议
TIMESTAMPDIFF(DAY, creation_date, now()) < ‘300’这个的逻辑是不是可以这样写
creation_date > current_date() - interval 300 day
不在列上做计算,还可以走索引

是个好方法,查询效率确实会高很多。
不过还是想找出这相同的SQL执行结果却不同的原因哈哈

你的sql是怎么执行的是先发占位符的sql,再传参嘛,可以把TIMESTAMPDIFF(DAY, creation_date, now())整个当成参数试一下