MySQL时间格式处理 13位时间戳转日期格式的完整流程

说实话,我之前处理过一堆1 3 位时间戳的数据,那会儿真是坑坑不少。
就拿我自己踩过的坑来说,这里头细节挺多的。

举个例子,我有个电商表,日志里存着1 3 位毫秒级时间戳。
直接用FROM_UNIXTIME(timestamp_ms/1 000)转是没错,但有个哥们儿问我为啥他本地跑出来的时间比我服务器上的晚8 个小时。
后来一查,才知道是时区问题——他的MySQL默认是Asia/Shanghai,而日志本来就是UTC时间戳。
这事儿得特别注意,直接用CONVERT_TZ解决,但前提是得先跑LOAD DATA LOCAL INFILE把时区表mysql.time_zone加载进去。

关于性能这块儿,我有个教训。
之前有个大表,几千万条记录,有哥们儿非要在WHERE子句里用FROM_UNIXTIME转时间戳再筛选。
结果你猜怎么着?索引全废了。
后来我们改用生成列,AS (FROM_UNIXTIME(timestamp_ms/1 000)),这招真管用,索引用上了,查询速度直接快了几个数量级。

要说最烦人的,还得是数据质量问题。
有回接上游数据,那时间戳里全是NULL和乱码字符。
直接转就崩了,所以必须加个IFNULL(timestamp_ms, 0)处理。
MySQL 8 +的TRY_CAST也能用,但说实话,我更习惯用CAST(... AS UNSIGNED),至少跑起来没那么多幺蛾子。

格式化这块儿,我个人是喜欢用DATE_FORMAT自己组合。
比如我有个报表需求,要按周统计,那就用%W,%M%D%Y这种格式。
不过要注意,%W(星期名)在MySQL里是英文,有时候得额外处理。
我以前为了这个事儿还折腾过自定义函数,现在想想纯属多此一举。

1 3 位和1 0位时间戳的区别,我倒没觉得复杂。
反正我接数据的时候,都会先加个CASE WHEN LENGTH(timestamp_ms) = 1 3 THEN ... END的判断,安全起见。

最后说个冷知识,FROM_UNIXTIME默认会根据MySQL服务器的时区来转换。
你要是服务器在东京,但数据是UTC的,那结果就会错。
这时候用CONVERT_TZ指定时区,但前提是得先LOAD DATA加载时区表,否则报错。
这点我踩坑过,当时以为是代码问题,结果一查手册才发现是时区表没加载。

这些是我真事儿,不是纸上谈兵。
你要是碰上类似问题,多半也在这些细节里。

MySQL时间戳与日期互转实战 where条件查询效率提升方法

上周,我那个朋友在MySQL里遇到个问题,就是时间戳和日期的转换,还有WHERE条件查询效率低。
他说,用UNIX_TIMESTAMP和FROM_UNIXTIME这些函数转换时间戳和日期挺方便,但用这些函数在WHERE条件里会导致索引失效,得想个法子。

2 02 3 年,我发现了一个方法,就是直接在WHERE条件里用时间戳,而不是用转换函数。
比如,如果你想查2 02 3 年1 0月2 6 日的记录,可以这样写:
sql SELECT FROM your_table WHERE record_time >= UNIX_TIMESTAMP('2 02 3 -1 0-2 6 00:00:00') AND record_time <= UNIX_TIMESTAMP('2 02 3 -1 0-2 6 2 3 :5 9 :5 9 ');
这种方法的好处是,索引列保持“纯净”,数据库可以直接通过索引树定位数据,避免了全表扫描。

还有个场景,比如有个订单表,其中created_at字段是时间戳类型,你想查某一天的订单,可以这样写:
sql SELECT order_id, created_at FROM orders WHERE created_at >= UNIX_TIMESTAMP('2 02 3 -1 0-2 6 00:00:00') AND created_at < UNIX> 至于优化WHERE条件查询的通用策略,我朋友说有几个要点:
1 . 合理使用索引,比如单列索引和复合索引。
2 . 选择正确的数据类型,比如日期/时间类型比VARCHAR更高效。
3 . 避免全表扫描的操作,比如避免LIKE '%keyword'。
4 . 优化子查询和连接,比如使用EXISTS代替IN。
5 . 使用EXPLAIN分析执行计划,找到查询瓶颈。

我朋友说,这样一优化,查询性能就能得到显著提升。
你看着办,这方法挺实用的。

MySQL日期格式化教程 13位时间戳转日期类型的解决方案

1 3 位时间戳转日期直接除1 000,用FROM_UNIXTIME()转。

FROM_UNIXTIME(timestamp_ms/1 000)转标准格式。

DATE_FORMAT()自定义格式,如'%Y-%m-%d'只显示日期。

MySQL5 .6 .4 +可用MOD()取毫秒,LPAD()补零。

反向转换用UNIX_TIMESTAMP()乘1 000。

精确转换需分离秒和毫秒,如FLOOR(UNIX_TIMESTAMP())。

MySQL8 .0.1 7 +用UNIX_TIMESTAMP(NOW(3 ))1 000。

旧版本手动拼接FLOOR(UNIX_TIMESTAMP(NOW()))1 000+FLOOR(MICROSECOND(NOW())/1 000)。

时区问题用UTC_TIMESTAMP()存UTC,应用层转时区。

DATETIME存固定时间点,TIMESTAMP受时区影响。

MySQL5 .6 .4 前不支持毫秒,需DATETIME(3 )或DATETIME(6 )。

1 3 位因毫秒级精度,除1 000因MySQL默认秒级处理。

你自己掂量。