TIMESTAMPDIFF最可靠但需注意单位为字符串且返回整数;精确小数需用秒差除60.0;UNIX_TIMESTAMP相减有時區和範圍風險;性能关键在字段类型与索引设计。

直接用 TIMESTAMPDIFF 最省心,但要注意单位陷阱
MySQL 提供的 TIMESTAMPDIFF 是计算时间差最可靠的方式,它能自动处理闰年、月末天数不一致、时区偏移(如果字段是 TIMESTAMP 类型)等问题。关键点在于:它的第一个参数是**时间单位**,且必须是字符串字面量,比如 'MINUTE',不是数字或变量。
常见错误是写成 TIMESTAMPDIFF(MINUTE, t1, t2)(漏引号),这会导致 SQL 报错:ERROR 1064 (42000): You have an error in your SQL syntax。
正确写法示例:
SELECT TIMESTAMPDIFF(MINUTE, '2024-03-15 10:20:00', '2024-03-15 11:35:45');
返回 75(不是 75.75),因为 TIMESTAMPDIFF 只返回整数,向下取整到分钟级——即只算完整经过的分钟数。
需要小数分钟(比如 75.75)?别用 TIMESTAMPDIFF,改用时间转秒再除
当业务要求精确到秒级的小数分钟(例如计算用户停留时长、API 响应耗时),TIMESTAMPDIFF(MINUTE, ...) 不够用。此时应统一转为秒,再除以 60.0:
-
TIMESTAMPDIFF(SECOND, start_time, end_time)得到总秒数(整数) - 除以
60.0(不是60),避免整数除法截断 - 结果自动转为
DECIMAL或FLOAT,保留小数
示例:
SELECT TIMESTAMPDIFF(SECOND, '2024-03-15 10:20:00', '2024-03-15 11:35:45') / 60.0;
返回 75.7500。注意:若输入含毫秒(如 DATETIME(3)),TIMESTAMPDIFF(SECOND, ...) 会丢弃毫秒;需用 TIMESTAMPDIFF(MICROSECOND, ...) 再除以 60000000.0 才能保留亚秒精度。
UNIX_TIMESTAMP 相减看似简单,但有隐性风险
有人习惯用 UNIX_TIMESTAMP(end) - UNIX_TIMESTAMP(start) 算秒差,再除以 60。这种方式在大多数场景下结果一致,但存在两个隐患:
- 若字段类型是
DATETIME且数据库时区与会话时区不一致,UNIX_TIMESTAMP()会按当前会话时区转换,可能引入偏差 - 若时间值超出 Unix 时间戳范围(
1970-01-01到2038-01-19),函数返回NULL,导致整个表达式失效
相比之下,TIMESTAMPDIFF 对 DATETIME 和 TIMESTAMP 都安全,且不依赖时区设置。除非你明确控制时区且确认时间在有效范围内,否则不建议用 UNIX_TIMESTAMP 相减。
性能差异很小,但索引和类型选择影响更大
三个函数本身的执行开销几乎可以忽略,真正影响查询效率的是字段类型和索引:
- 用
TIMESTAMP而非DATETIME存储时间,可减少存储空间(4 字节 vs 8 字节),对大表有微弱优势 - 如果频繁按时间范围 + 分钟差过滤(例如
WHERE TIMESTAMPDIFF(MINUTE, created_at, NOW()) > 30),这个表达式无法走索引——必须把条件改写为created_at 才能命中 <code>created_at上的索引 - 避免在 WHERE 或 ORDER BY 中对时间字段套函数,这是性能隐形杀手
实际线上慢查里,90% 的时间差相关性能问题,根源不在选哪个函数,而在于是否让时间条件保持“索引友好”。


















