MySQL时间戳索引失效SQL慢查问题排查

最近一次sql慢查的排查过程其中一个点是自己之前没有关注过的,分享一下

 

首先有一张表tableA {

    id 主键 自增

    create_time 创建时间 默认mysql当前时间自动填充

    ..... 其他字段

},

表结构中含有常规的id, create_time, update_time之类的字段,create_time字段建了索引;

 

tableA每天会在上午6点50左右接收一批同步数据,数据量大约在40000+

该表保留一周的数据,因此该表数据的总行数目前维持在35W+

查询的sql使用了create_time的查询条件,查询的时间区间时1天,理论上能查出的数据在40000+,占数据总量的约11%,理应走索引查询

 

但是,实际的执行过程显示,该sql还是走了全表扫描;经验证,即使查询条件只有create_time也是走了全表扫描;

我们尝试了缩短查询时间区间,当查询区间内不含数据时才走了索引查询,但是一旦涵盖了当天同步过来的数据,就变成了全表扫描;

于是我们对数据的内容进行了分析,发现由于这批数据基本都是在那个时间点同步过来,create_time是数据insert到表中时的当前时间自动获取的默认值,因此create_time会有大量的重复;

我们select count(distinct create_time) from tableA后得到35W+的数据,create_time只有97

我们再慢查SQL的部分统计了count(distinct create_time),得到的create_time是11种,

结论:

由此我们断定,像这样的根茎节点非常少,一个父节点下面挂了3700多个叶子节点的情况,即便是我们对这个create_time建了索引,但是走索引和不走索引相差无几,故mysql引擎选择了全表扫描;

在建立索引的时候,要根据列基数来建立,列基数=列中不同的数据/除以总数据,越接近1表示重复数据越少,越适合建立索引。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值