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

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

美好的周五

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

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

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

抓住那只bug

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

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

获取今天之前登录的用户列表的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不崩溃才怪。

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

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

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

尝试1:

SQL的值加上引号

如上图,果然极快。

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

尝试2:

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

再次执行SQL:

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

相应结果提升N倍:

至此,问题处理完毕。

总结

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

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

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

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

  1. MySql 时间戳存char还是存int?

    一次小事故,让我对时间戳存char还是存int有了深刻的印象. 生产环境的sql条件涉及到时间戳字段的大小比较(between and),当时设计的时间戳类型是char(10),结果当数据量达到200 ...

  2. 一次线上事故,让我对MySql的时间戳存char(10)还是int(10)有了全新的认识

    美好的周五 周五的早晨,一切都是那么美好. 然鹅,10点多的时候,运营小哥哥突然告诉我后台打不开了,我怀着一颗"有什么大不了的,估计又是(S)(B)不会连wifi"的心情,自信的打 ...

  3. Mysql时间戳转Java时间戳

    MySQL 时间戳和Java返回的时间戳是不一样的 例如: 当前时间是 2014-08-04 10:42:55.204000 使用mysql时间戳函数UNIX_TIMESTAMP 返回的结果为: 14 ...

  4. mysql 字符串类型 char varchar

    字符类型用在存储名字.邮箱地址.家庭住址等描述性数据   char指的是定长字符,varchar指的是变长字符 #官网:https://dev.mysql.com/doc/refman/5.7/en/ ...

  5. Mysql的 时间戳转换 和 c# 的时间戳转换 (以秒来进行转换,非毫秒,主要是mysql不能存毫秒)

    Mysql 时间戳函数 => 从时间 转成 时间戳   UNIX_TIMESTAMP() 获取当前服务器时间的时间戳 UNIX_TIMESTAMP('2013-01-01 12:33:19') ...

  6. FROM_UNIXTIME 格式化MYSQL时间戳函数

    FROM_UNIXTIME 格式化MYSQL时间戳函数 对MYSQL没有进行过深入的研究,基础知识匮乏,一遇到问题只能手册,看来要把MYSQL的学习安排进时间表了. 函数:FROM_UNIXTIME作 ...

  7. MySQL时间戳和时间格式转换函数

    MySQL时间戳和时间格式转换函数:unix_timestamp and from_unixtime unix_timestamp将时间转化成时间戳格式.from_unixtime将时间戳转化成时间格 ...

  8. MySQL 时间戳(Timestamp)函数

    1. MySQL 获得当前时间戳函数:current_timestamp, current_timestamp() mysql> select current_timestamp, curren ...

  9. MySQL Yum存储库 安装、升级、集群

    添加MySQL Yum存储库 首先,将MySQL Yum存储库添加到系统的存储库列表中.按着这些次序: 在http://dev.mysql.com/downloads/repo/yum/上转到MySQ ...

  10. MySQL 时间戳(Timestamp)函数

    1. MySQL 获得当前时间戳函数:current_timestamp, current_timestamp() mysql> select current_timestamp, curren ...

随机推荐

  1. Facade 外观模式简介与 C# 示例【结构型5】【设计模式来了_10】

    〇.简介 1.什么是外观模式? 一句话解释:   将一系列需要一起进行的操作,封装到一个类中,通过对某一个方法的调用,自动完成一系列操作. 外观模式是一种简单而又实用的设计模式,它的目的是提供一个统一 ...

  2. 阿里发布AI编码助手:通义灵码,兼容 VS Code、IDEA等主流编程工具

    今天是阿里云栖大会的第一天,相信场外的瓜,大家都吃过了.这里就不说了,有兴趣可以看看这里:云栖大会变成相亲现场,最新招婿鄙视链来了... . 这里主要说说阿里还发布了一款AI编码助手,对于我们开发者来 ...

  3. springboot项目在docker中运行

    前端时间需要把项目打包到docker中运行,于是就让组员去探索,最后整个过程是这样的. 首先我们做java开发,一般都是使用springboot开发,开发完成,我们需要把springboot项目打包成 ...

  4. Java表达式引擎选型调研分析

    1 简介 我们项目组主要负责面向企业客户的业务系统,企业的需求往往是多样化且复杂的,对接不同企业时会有不同的定制化的业务模型和流程.我们在业务系统中使用表达式引擎,集中配置管理业务规则,并实现实时决策 ...

  5. 记录jdk17相对于jdk8增加的一下主要语法糖和新特性

    jdk17 发布已经好久了,作为java的长期支持版本,引入了许多有趣且实用的新特性.这些特性不仅提高了开发效率,还增强了语言的表现力和安全性.并且是SpringBoot 3.0以后版本的硬性要求,之 ...

  6. Android学习day02【页面布局的练习】

    在网上找了一些图片,只用最简单的颜色进行区分,目的是熟悉线性布局和相对布局 下面是我找到的简单的Android页面,你也可以尝试以下' 下面是我的实现代码 第一个

  7. 31. 干货系列从零用Rust编写正反向代理,HTTP限流的实现(limit_req)

    wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代 ...

  8. jdk9模块化

    JDK 9是Java开发语言的一个重大版本.其中最令人兴奋的新特性之一是模块化系统.模块化系统提出了一种新的代码组织方式,它可以帮助开发人员更好地组织和管理代码,从而使Java应用程序更加可维护.可扩 ...

  9. VCS用法

    1.时钟频率点击,鼠标左键点击波形上升沿,中间滚轮点击,然后选择hz,就显示当前信号时钟频率. 2.窗口乱掉,找不到文件列表,右下角点击弹出选择instance. 3.bus地址查找,选择信号,然后蓝 ...

  10. JQuery_1

    1.概念:一个JavaScript框架.简化js开发 JavaScript框架:本质上就是一些js文件,封装了js的原生代码. 2.快速入门: 1.步骤 1.下载JQuery jquery.xxx.j ...