mysql时间类型字段的优化技巧

mysql时间类型字段的优化技巧

最近开发一个功能时需要查询今天开播的主播用户。在业务上我们有一个数据表存储了主播每次开播的记录。表中有一个时间类型的字段表示主播开播时间。(为了业务安全,这里用time字段表明实际字段. record表示数据表)

第一种实现

在开始实现的时候想到的就是 time = 今天这种实现逻辑上比较直接。

select distinct userId
  from record
 where date_format(time, '%Y%m%d')= 
 date_format(now(), '%Y%m%d')

可以看到关键就是where后的date_format函数了。对日期格式进行转换。这个sql在测试环境跑没有什么问题,在线上跑之后一直报timeout。最后查看了慢语句汇总。发现上面的sql也俨然在列。

第二种实现

实现思路

    select distinct userId
     from record
     where  
     time >= 'YYYY-mm-dd 00:00:00'
     and  time <= 'YYYY-mm-dd 23:59:59'

具体实现(也可以从服务层穿参这样sql显的就不复杂了):

select distinct userId from record
 where time >=
 (SELECT  str_to_date(DATE_FORMAT( NOW(), '%Y-%m-%d'), '%Y-%m-%d %H:%i:%s'))
and time <=(select DATE_ADD( DATE_ADD(str_to_date(DATE_FORMAT(NOW(),'%Y-%m-%d'),'%Y-%m-%d %H:%i:%s'), INTERVAL 1 DAY),INTERVAL -1 SECOND));

两种实现对比

虽然两种实现都可以完成这个功能,但是第二种在线上跑没有性能问题。此时查看sql的执行计划explain
发现两个的执行计划的row相差1000倍,并且单次测量第一种执行时间需要3000多毫秒,而第二种只需要4ms

first row second row
3000 3
first time second time
3300ms 4ms

原因是date_format这种需要对日期进行转换,需要查询出所有行进行过滤。而第二种可以利用在time上建立索引,查询极快。

发布了121 篇原创文章 · 获赞 56 · 访问量 167万+

猜你喜欢

转载自blog.csdn.net/u013565163/article/details/87223818
今日推荐