MySQL存储时间类型选择的问题讲解

 更新时间:2019年03月20日 16:32:25   作者:CODETC  
今天小编就为大家分享一篇关于MySQL存储时间类型选择的问题讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

MySQL中存储时间通常会用datetime类型,但现在很多系统也用int存储unix时间戳,它们有什么区别?本人总结如下:

int

(1)4个字节存储,INT的长度是4个字节,存储空间上比datatime少,int索引存储空间也相对较小,排序和查询效率相对较高一点点

(2)可读性极差,无法直观的看到数据

TIMESTAMP

(1)4个字节储存

(2)值以UTC格式保存

(3)时区转化 ,存储时对当前的时区进行转换,检索时再转换回当前的时区。

(4)TIMESTAMP值不能早于1970或晚于2037

datetime

(1)8个字节储存

(2)与时区无关

(3)以'YYYY-MM-DD HH:MM:SS'格式检索和显示DATETIME值。支持的范围为'1000-01-01 00:00:00'到'9999-12-31 23:59:59'

随着Mysql性能越来越来高,个人觉得关于时间的存储方式,具体怎么存储看个人习惯和项目需求吧

分享两篇关于int vs timestamp vs datetime性能测试的文章

Myisam:MySQL DATETIME vs TIMESTAMP vs INT 测试仪

CREATE TABLE `test_datetime` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`datetime` FIELDTYPE NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM;

机型配置

  • kip-locking
  • key_buffer = 128M
  • max_allowed_packet = 1M
  • table_cache = 512
  • sort_buffer_size = 2M
  • read_buffer_size = 2M
  • read_rnd_buffer_size = 8M
  • myisam_sort_buffer_size = 8M
  • thread_cache_size = 8
  • query_cache_type = 0
  • query_cache_size = 0
  • thread_concurrency = 4

测试

DATETIME   14111 14010        14369     130000000
TIMESTAMP  13888        13887        14122     90000000
INT        13270        12970        13496     90000000

执行mysql

mysql> select * from test_datetime into outfile ‘/tmp/test_datetime.sql';
Query OK, 10000000 rows affected (6.19 sec)

mysql> select * from test_timestamp into outfile ‘/tmp/test_timestamp.sql';
Query OK, 10000000 rows affected (8.75 sec)

mysql> select * from test_int into outfile ‘/tmp/test_int.sql';
Query OK, 10000000 rows affected (4.29 sec)

alter table test_datetime rename test_int;
alter table test_int add column datetimeint INT NOT NULL;
update test_int set datetimeint = UNIX_TIMESTAMP(datetime);
alter table test_int drop column datetime;
alter table test_int change column datetimeint datetime int not null;
select * from test_int into outfile ‘/tmp/test_int2.sql';
drop table test_int;

So now I have exactly the same timestamps from the DATETIME test, and it will be possible to reuse the originals for TIMESTAMP tests as well.

mysql> load data infile ‘/export/home/ntavares/test_datetime.sql' into table test_datetime;
Query OK, 10000000 rows affected (41.52 sec)
Records: 10000000 Deleted: 0 Skipped: 0 Warnings: 0

mysql> load data infile ‘/export/home/ntavares/test_datetime.sql' into table test_timestamp;
Query OK, 10000000 rows affected, 44 warnings (48.32 sec)
Records: 10000000 Deleted: 0 Skipped: 0 Warnings: 44

mysql> load data infile ‘/export/home/ntavares/test_int2.sql' into table test_int;
Query OK, 10000000 rows affected (37.73 sec)
Records: 10000000 Deleted: 0 Skipped: 0 Warnings: 0

As expected, since INT is simply stored as is while the others have to be recalculated. Notice how TIMESTAMP still performs worse, even though uses half of DATETIME storage size.

Let's check the performance of full table scan:

mysql> SELECT SQL_NO_CACHE count(id) FROM test_datetime WHERE datetime > ‘1970-01-01 01:30:00′ AND datetime < ‘1970-01-01 01:35:00′;
+———–+
| count(id) |
+———–+
|  211991 |
+———–+
1 row in set (3.93 sec)

mysql> SELECT SQL_NO_CACHE count(id) FROM test_timestamp WHERE datetime > ‘1970-01-01 01:30:00′ AND datetime < ‘1970-01-01 01:35:00′;
+———–+
| count(id) |
+———–+
|  211991 |
+———–+
1 row in set (9.87 sec)

mysql> SELECT SQL_NO_CACHE count(id) FROM test_int WHERE datetime > UNIX_TIMESTAMP('1970-01-01 01:30:00′) AND datetime < UNIX_TIMESTAMP('1970-01-01 01:35:00′);
+———–+
| count(id) |
+———–+
|  211991 |
+———–+
1 row in set (15.12 sec)

Then again, TIMESTAMP performs worse and the recalculations seemed to impact, so the next good thing to test seemed to be without those recalculations: find the equivalents of those UNIX_TIMESTAMP() values, and use them instead:

mysql> select UNIX_TIMESTAMP('1970-01-01 01:30:00′) AS lower, UNIX_TIMESTAMP('1970-01-01 01:35:00′) AS bigger;
+——-+——–+
| lower | bigger |
+——-+——–+
| 1800 |  2100 |
+——-+——–+
1 row in set (0.00 sec)

mysql> SELECT SQL_NO_CACHE count(id) FROM test_int WHERE datetime > 1800 AND datetime < 2100;
+———–+
| count(id) |
+———–+
|  211991 |
+———–+
1 row in set (1.94 sec)

Innodb:MySQL DATETIME vs TIMESTAMP vs INT performance and benchmarking with InnoDB

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • MySQL优化之缓存优化(续)

    MySQL优化之缓存优化(续)

    本文是MySQL优化系列文章的第一篇缓存优化的续篇,为大家更为详细的介绍缓存优化的方方面面,希望大家能够喜欢
    2017-03-03
  • mysql注入之长字符截断,orderby注入,HTTP分割注入,limit注入方式

    mysql注入之长字符截断,orderby注入,HTTP分割注入,limit注入方式

    这篇文章主要介绍了mysql注入之长字符截断,orderby注入,HTTP分割注入,limit注入方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • MySQL中的undo日志

    MySQL中的undo日志

    这篇文章主要介绍了MySQL中的undo日志的相关资料,帮助大家更好的理解和学习MySQL的相关知识,感兴趣的朋友可以了解下
    2020-11-11
  • windows2008 64位系统下MySQL 5.7绿色版的安装教程

    windows2008 64位系统下MySQL 5.7绿色版的安装教程

    这篇文章主要给大家分享了在windows2008 64位系统下MySQL 5.7绿色版的安装教程,文中将安装步骤介绍的非常详细,相信会对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-05-05
  • MySQL基础教程之DML语句详解

    MySQL基础教程之DML语句详解

    DML 语句是指对数据库中表的记录进行的操作,下面这篇文章主要给大家介绍了关于MySQL基础教程之DML语句的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2021-12-12
  • mysql字符集乱码问题解决方法介绍

    mysql字符集乱码问题解决方法介绍

    解决乱码的方法是,在执行SQL语句之前,将MySQL以下三个系统参数设置为与服务器字符集character-set-server相同的字符集
    2012-05-05
  • 设置mysql5.7编码集为utf8mb4的方法

    设置mysql5.7编码集为utf8mb4的方法

    移动端的表情或者一些emoji是4字节的,但是utf-8是3字节的,这篇文章主要介绍了设置mysql5.7编码集为utf8mb4的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • Mysql Sql 语句练习题(50道)

    Mysql Sql 语句练习题(50道)

    mysql一直作为比较热门的数据库存储,搭配php使用简直是绝配,mysql的sql语句也是很重要的一门课,这里为大家分享一下sql语句,大家可以试试
    2020-12-12
  • mysql数据损坏,如何通过ibd和frm文件批量恢复数据库数据

    mysql数据损坏,如何通过ibd和frm文件批量恢复数据库数据

    这篇文章主要介绍了mysql数据损坏,如何通过ibd和frm文件批量恢复数据库数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • MySql8.023安装过程图文详解(首次安装)

    MySql8.023安装过程图文详解(首次安装)

    这篇文章主要介绍了MySql8.023安装过程(首次安装),本文分步骤给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03

最新评论