6

一次事故,我对MySQL时间戳存char(10)还是int(10)有了全新的认识

 3 years ago
source link: https://my.oschina.net/u/4526289/blog/5062580
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

摘要:char类型字段想走索引的话,必须用引号括起来。如果是时间戳等类型的纯数字,建议还是存为int型吧。

本文分享自华为云社区《一次事故,我对MySql时间戳存char(10)还是int(10)有了全新的认识》,原文作者:奔四码农 。

美好的周五

周五的早晨,一切都是那么美好。

v2-2f3c961d26b0747fb95246496eacb0be_720w.jpg

然而,10点多的时候,运营小哥哥突然告诉我后台打不开了,我怀着一颗“有什么大不了的,估计又是他不会连wifi”的心情,自信的打开了网址,果然,真打不开了。

v2-6b0e57ad07874460886e5e12ebe5e59c_720w.jpg

这是存心让我过不好周末呀!

抓住那只bug

经过我缜密的排查,发现是一个“获取今天之前登录的用户”接口调用严重超时:

v2-66e9af444e768c7f391134d3df642778_720w.jpg

这个接口其实调用的数据表不多,在MySQL只读取了1张表,表结构如下:

v2-9ae2fb8557bac9175966ef090b607abb_720w.jpg

获取今天之前登录的用户列表的SQL如下:

SELECT u.email, log.user_id
FROM `user` u
LEFT JOIN `log_user_active` log ON u.user_id = log.user_id
WHERE log.`log_dtime` <1634567890
LIMIT 0 , 30

这只是一个简单的SQL查询,并没有什么高精尖、复杂的查询为什么这么慢?由于log_user_active的数据量最大,所以猜想应该是log_user_active表出了问题,为了排查原因,我把SQL又简化了下,去掉了JOIN直接简化为:

SELECT log.user_id
FROM `log_user_active`
WHERE `log_dtime` <1551784072
LIMIT 0 , 30

经执行,这个语句花了将近1秒。。。如果多人同时访问,MySQL不崩溃才怪。

v2-6286c2802e3bfcd184ca25b90e41d61b_720w.jpg

此时,应该确信是这个表出问题无疑了,但是字段log_dtime明明建立了索引,怎么还这么慢呢?

经过各种百度,终于发现问题所在:由于log_dtime设计的是char类型。如果想让它走索引,查询的时候,值必须要加引号,说明这是个字符串,否则是不会走索引的。我的数据恰巧都是数字组成(时间戳),查询的时候也没有刻意去加引号,导致查询的时候不走索引。

这就是问题所在了,于是进行如下尝试:

尝试1:

SQL的值加上引号

v2-2a8e6a6a0fa51df7d157f480577eb430_720w.jpg

如上图,果然极快。

但是这样的话,需要改好多代码,我想想还是尝试下方法2吧。

尝试2:

果断将数据表结构log_dtime设计为INT型,如图:

v2-e0b72e13012e5dec2694dff0397f1614_720w.jpg

再次执行SQL:

SELECT log.user_id
FROM `log_user_active`
WHERE `log_dtime` <1551784072
LIMIT 0 , 30

相应结果提升N倍:

v2-f492634732e00ca060e1d099794dd899_720w.jpg

至此,问题处理完毕。

总结

char类型字段想走索引的话,必须用引号括起来。如果是时间戳等类型的纯数字,建议还是存为int型吧。

v2-d8d38a06c46ebaa6cc6680a718965e11_720w.jpg

愉快的周末,又向我招手了。

点击关注,第一时间了解华为云新鲜技术~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK