Mysql - 如何决定用 datetime、timestamp、int 哪种类型存储时间戳?
背景
- 数据表都很可能会有一两个字段需要保存日期时间数据,那应该用什么 Mysql 类型来保存呢?
- 前面讲过 datetime、timestamp、int 的方式来保存日期时间
本篇文章会对 datetime、timestamp、int 进行比较,然后对一些典型的查询进行基准测试,来决定什么情况下使用哪种数据类型
整体对比表
加粗是缺点
|
Feature |
datetime |
timestamp |
Int (存储 Unix time) |
|
本地时间表示 |
Yes |
Yes |
No,如果要表示为本地时间需要借助转换函数,比如FROM_UNIXTIME() |
|
存储小数秒 |
Yes,高达 6 位精度 |
Yes,高达 6 位精度 |
No |
|
有效范围 |
'1000-01-01 00:00:00.000000' |
'1970-01-01 00:00:01.000000' |
如果是无符号, |
|
自动初始化 (MySQL 5.6.5+) |
Yes |
Yes |
No |
|
可读性好 |
Yes |
Yes |
No, 必须转换才能知道具体时间点 |
|
存储时间值会转换为 UTC 时间 |
No |
Yes |
No |
|
可以改成其他了诶性 |
Yes, 如果结果值在有效时间范围内 |
Yes |
Yes, 如果结果值在有效时间范围内并使用了转换函数 |
|
存储要求 (MySQL 5.6.4+) |
5 bytes (加上最多 3 个字节的小数秒,如果使用) |
4 bytes(加上最多 3 个字节的小数秒,如果使用) |
4 bytes (no fractional seconds allowed) |
接下来对 int、timestamp、datetime 的性能进行基准测试
- 这里直接展示结果,不展示过程了(因为只需要关注结果即可)
- 感兴趣可以看:https://vertabelo.com/blog/
- 这里会使用 sysbench、mysqlslap 两个性能测试工具
测试一:选择日期范围内的值
下列查询均是从 1,497,421 个可用数据中返回 75,706 行
datetime
SELECT SQL_NO_CACHE
measured_on
FROM
vertabelo.datetimemeasures m
WHERE
m.measured_on > '2016-01-01 00:00:00.0'
AND m.measured_on < '2016-02-01 00:00:00.0';
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 152 | 296 |
| Max | 1261 | 3203 |
| Average | 362 | 809 |
timestamp
SELECT SQL_NO_CACHE
measured_on
FROM
vertabelo.timestampmeasures m
WHERE
m.measured_on > '2016-01-01 00:00:00.0'
AND m.measured_on < '2016-02-01 00:00:00.0';
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 214 | 359 |
| Max | 1389 | 3313 |
| Average | 431 | 1004 |
int(使用 FROM_UNIXTIME 转换函数)
SELECT SQL_NO_CACHE
measured_on
FROM
vertabelo.inttimestampmeasures m
WHERE
FROM_UNIXTIME(m.measured_on) > '2016-01-01 00:00:00.0'
AND FROM_UNIXTIME(m.measured_on) < '2016-02-01 00:00:00.0';
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 2472 | 7968 |
| Max | 6554 | 10312 |
| Average | 4107 | 8527 |
int
SELECT SQL_NO_CACHE
measured_on
FROM
vertabelo.inttimestampmeasures m
WHERE
m.measured_on > 1451617200
AND m.measured_on < 1454295600;
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 88 | 171 |
| Max | 275 | 2157 |
| Average | 165 | 514 |
结论
- 两个基准测试工具都表明 datime 比 timestamp 和 int(使用转换函数) 快
- 但是 datetime 并不比直接用 int 数字快
| Avg response time (ms) | Sysbench | 相对于 datetime 的速度 | mysqlslap | 相对于 datetime 的速度 |
|---|---|---|---|---|
| datetime | 362 | - | 809 | - |
| timestamp | 431 | 19% slower | 1004 | 24% slower |
| int(使用转换函数) | 4107 | 1134% slower | 8527 | 1054% slower |
| int | 165 | 55% faster | 514 | 36% faster |
测试二:选择星期一的数据
下列查询均是从 1,497,421 个可用数据中返回 221,850 行
datetime
SELECT SQL_NO_CACHE measured_on
FROM
vertabelo.datetimemeasures m
WHERE
WEEKDAY(m.measured_on) = 0 #MONDAY;
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 1874 | 4343 |
| Max | 6168 | 7797 |
| Average | 3127 | 6103 |
timestamp
SELECT SQL_NO_CACHE
measured_on
FROM
vertabelo.timestampmeasures m
WHERE
WEEKDAY(m.measured_on) = 0 #MONDAY;
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 2688 | 5953 |
| Max | 6666 | 13531 |
| Average | 3653 | 8412 |
int(使用 FROM_UNIXTIME 转换函数)
SELECT SQL_NO_CACHE
measured_on
FROM
vertabelo.inttimestampmeasures m
WHERE
WEEKDAY(FROM_UNIXTIME(m.measured_on)) = 0 #MONDAY;
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 2051 | 5844 |
| Max | 7007 | 10469 |
| Average | 3486 | 8088 |
结论
- 两个基准测试工具都表明 datime 比 timestamp 和 int(使用转换函数) 快
- 但在这个测试中,int(使用转换函数)比 timestamp 更快
| Avg response time (ms) | Sysbench | 相对于 datetime 的速度 | mysqlslap | 相对于 datetime 的速度 |
|---|---|---|---|---|
| Datetime | 3127 | - | 6103 | - |
| Timestamp | 3653 | 17% slower | 8412 | 38% slower |
| INT | 3486 | 11% slower | 8088 |
32% slower |
测试三:统计星期一的数据量
下列查询均是从 1,497,421 个可用数据中返回 1 行
datetime
SELECT SQL_NO_CACHE
COUNT(measured_on)
FROM
vertabelo.datetimemeasures m
WHERE
WEEKDAY(m.measured_on) = 0 #MONDAY;
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 1720 | 4063 |
| Max | 4594 | 7812 |
| Average | 2797 | 5540 |
timestamp
SELECT SQL_NO_CACHE
COUNT(measured_on)
FROM
vertabelo.timestampmeasures m
WHERE
WEEKDAY(m.measured_on) = 0 #MONDAY;
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 1907 | 4578 |
| Max | 5437 | 10235 |
| Average | 3408 | 7102 |
int(使用 FROM_UNIXTIME 转换函数)
SELECT SQL_NO_CACHE
COUNT(measured_on)
FROM
vertabelo.inttimestampmeasures m
WHERE
WEEKDAY(FROM_UNIXTIME(m.measured_on)) = 0 #MONDAY;
| Response time (ms) | Sysbench | mysqlslap |
|---|---|---|
| Min | 2108 | 5609 |
| Max | 4764 | 9735 |
| Average | 3307 | 7416 |
结论
- 两个基准测试工具都表明 datime 比 timestamp 和 int(使用转换函数) 快
- 但在这个测试中,int(使用转换函数)比 timestamp 更快
| Avg response time (ms) | Sysbench | 相对于 datetime 的速度 | mysqlslap | 相对于 datetime 的速度 |
|---|---|---|---|---|
| Datetime | 2797 | - | 5540 | - |
| Timestamp | 3408 | 22% slower | 7102 | 28% slower |
| INT | 3307 | 18% slower | 7416 | 33% slower |
最终结论
使用 datetime 应该是绝大多数场景下的最佳选择,因为
- 它更快
- 它可读性更好,无需转换
- 没有时区切换的问题
- 它仅比 timestamp 多使用 1 个字节,但存储的时间范围却非常大
做抉择
- 如果只是想存储简单的 unix 时间戳,那么使用 int 是最佳选择,因为它非常快,和使用普通数字一样
- 而如果要根据时区进行存储日期时间,那么就应该使用 timestamp
- 否则绝大多数情况下推荐使用 datetime
Mysql - 如何决定用 datetime、timestamp、int 哪种类型存储时间戳?的更多相关文章
- Mysql 实战关于date,datetime,timestamp类型使用
最近在做一个项目 项目中 不同的小伙伴同时在不同的业务模块中用到了date,datetime,timestamp这三个类型 特别是datetime,timestamp这两个 如果不能理解到位 其实很 ...
- mysql中tinyint、smallint、int和bigint类型的用法区别
mysql中tinyint.smallint.int和bigint类型的用法区别: 在MySQL的数据类型中,Tinyint的取值范围是:带符号的范围是-128到127.无符号的范围是0到255(见官 ...
- Mysql时间存储类型优缺点?DATETIME?TIMESTAMP?INT?
TIMESTAMP 4个字节储存;值以UTC格式保存;.时区转化 ,存储时对当前的时区进行转换,检索时再转换回当前的时区. DATETIME 8个字节储存;实际格式储存;与时区无关;datetime ...
- Mysql中date,time,datetime,timestamp的区别
区别: timestamp:时间戳.北京时间1970年01月01日08时00分00秒 起至现在的总秒数. datetime:带时分秒的完整时间,例如:1970-01-01 10:00:00 date: ...
- DateTime?,也是一种类型,代表DateTime或NULL两种类型,在处理空时间时比较有用
public static DateTime? GetDateTimeFromStr(string date) { if (date.Trim() == string.Empty) return nu ...
- mysql中float、double、decimal三种类型,以及数值产生误差的原因
单精度浮点数用4字节(32bit)表示浮点数,采用IEEE754标准的计算机浮点数,在内部是用二进制表示的,如:7.22用32位二进制是表示不下的,所以就导致不精确了,存取会出现误差. mysql中f ...
- 简述MySQL数据库中的Date,DateTime,TimeStamp和Time类型
DATETIME类型 定义同时包含日期和时间信息的值时.MySQL检索并且以'YYYY-MM-DD HH:MM:SS'格式显示DATETIME值,支持的范围是'1000-01-01 00:00:00' ...
- mysql5.6 TIME,DATETIME,TIMESTAMP
[背景] 5.6.4以后时间类型(TIME,DATETIME,TIMESTAMP)支持微秒 DATETIME范围 :'1000-01-01 00:00:00.000000' to '9999-12-3 ...
- Mysql 5.7 系列命令 timestamp类型的字段不能设默认值为“0000-00-00 00:00:00” 要设为`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新',
一.show相关命令语句 1.查看表的索引 show index from tbl_name; 1 table:表名 non_unique:索引是非唯一的?.0否,唯一是索引的.1是,是非唯一索引.( ...
随机推荐
- [转载]SELinux安全系统基础
链接:http://www.cnblogs.com/xiaoluo501395377/archive/2013/05/26/3100444.html 本篇随笔将记录一下学习SELinux的一些心得与体 ...
- 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙看这篇或许真的够了 | 百篇博客分析OpenHarmony源码 | v50.06
百篇博客系列篇.本篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙防掉坑指南 | 51.c.h.o 编译构建相关篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙防掉 ...
- 数据库管理软件navicate12的激活和安装
前言 太多做测试或开发的小伙伴需要写sql语句,激活版navicat版本它来了 准备软件 navicat12安装包 navicat注册机 百度网盘下载链接(永久有效): 链接:https://pa ...
- Java(一)——基础知识
引言 之前一直对 Java 怀有固执的偏见,以为 Java 是编写前端的语言,作为一个机械生,非常抗拒去学它. 但是最近接触一点以后,完全改观了先前的看法,于是开启了对 Java 的大学习. 一.数据 ...
- asp.net core 中配合响应 html5 的音视频播放流,以及文件下载
一.asp.net core 中配合响应 html5 的音视频播放流,以及文件下载 问题描述: 目前测试了在 Windows(谷歌浏览器).Android(系统浏览器.QQ.微信).iOS 三个系统不 ...
- disruptor笔记之八:知识点补充(终篇)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 9.亿级流量电商系统JVM模型参数预估方案
1. 需求分析 大促在即,拥有亿级流量的电商平台开发了一个订单系统,我们应该如何来预估其并发量?如何根据并发量来合理配置JVM参数呢? 假设,现在有一个场景,一个电商平台,比如京东,需要承担每天上亿的 ...
- 题解 「THUPC 2017」小 L 的计算题 / Sum
题目传送门 题目大意 给出 \(a_{1,2,...,n}\),对于 \(\forall k\in [1,n]\) ,求出: \[\sum_{i=1}^{n}a_i^k \] \(n\le 2\tim ...
- redis两种持久化策略/存储模式
redis的持久化策略 RDB,即 Redis DataBase,以快照形式将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的dump文件,达到数据恢复. 默认开启,见redis ...
- nginx源码编译安装(详解)
nginx编译安装 安装步骤: 官网下载合适的版本,建议选择稳定版本. 官网地址:https://nginx.org wget https://nginx.org/download/nginx-1.2 ...