海石花47
1
【 TiDB 使用环境】生产环境
【 TiDB 版本】老环境v3.0 新环境v6.1
【复现路径】
如下的sql:
SELECT
*
FROM
inquiry_order
WHERE
doctor_receive_time >= 20230313
【遇到的问题:问题现象及影响】
前提:新老环境的表结构一致,时间字段存在索引
以上的sql 在老环境v3.0 下的执行计划走了索引,如下:
IndexLookUp_10 613.56 root
├─IndexScan_8 613.56 cop table:inquiry_order, index:doctor_receive_time, range:[2023-03-13 00:00:00,+inf], keep order:false
└─TableScan_9 613.56 cop table:inquiry_order, keep order:false
在新环境v6.1 下的执行计划没有走索引(全表扫描),如下:
TableReader_7 4503096.80 root data:Selection_6
└─Selection_6 4503096.80 cop[tikv] ge(cast(dwd.inquiry_order.doctor_receive_time, double BINARY), 2.0230313e+07)
└─TableFullScan_5 5628871.00 cop[tikv] table:inquiry_order keep order:false
问题: 表结构一致,字段有索引,字段是datetime格式,为何新老版本的 处理方式不同?
海石花47
2
看起来是老版本 自动将 20230313转化为 datetime格式,然后走了索引? 新版本做不到吗?
海石花47
3
感觉是 20230313 和 ‘2023-03-13’ 是两个不一样的值??? 这两个数据量都不一样
海石花47
4
这个不是自动转换吗? 必须要手动用 cast(20230313 as date) 这样来转化吗??
海石花47
5
20230313000000 好像才会被认为是 ‘2023-03-13 00:00:00’?? 如果单单是 20230313 可能会被认为是很早之前的时间戳?? 为啥3.0版本就可以呢,老版本里 20230313000000 跟 20230313 都可以直接当条件且结果一样。
应该是字符串和数字的问题吧?如果你写字符串会把字符串转换为datetime类型和表数据比对,如果你写数字会把表数据的字符类型转换为数字型进行比对,相当于字段做了隐式转换,而做了隐式转换之后,字段上的索引就用不上了啊,3.0能走索引反而感觉很奇葩啊。。。
海石花47
8
主要问题是,20230313 转换之后 不是2023-03-13 。。。time > 这两个值,是不一样的结果,就很迷
2023这种是数字吧 引号包含才是字符串 字符串自动转换成时间 数字不会
帖子里点你自己的头像,然后偏好设置,然后点头像图片旁边的修改按钮就能上传了
海石花47
16
不对,我的意思是 你把第一个sql 的’20230313’ 引号去掉,变成数值类型:
time> 20230313
time> ‘2023-03-13’
以上两个写法,v6.1 里结果不一致, v3.0 里结果一致。
海石花47
18
我改成 cast(20230313 as date) 就没事了,我就是好奇,为啥新老版本的处理方式不一样
海石花47
19
话是这样说没错。。但是官方文档里好像也没说明,就疑惑
不是,数字应该就是这样的,用数字关联datetime类型,转换是表中的数据从datetime类型隐式转换成了数字,用字符串datetime类型,转换是你的条件 ‘2023-03-13’从字符串类型隐式转换成了datetime。