mysql大翻页limt 1700,100慢优化方案

1、引言

公司有个需求,统计短信系统每天status没成功的电话号码,然后进行统计分析。为了省事,我直接用了现成的sql, 该sql是分页,每次筛选limit一百条,最后合并下,最后不就得出所有的手机号了吗?

select id from smss where type='0' and status='0' and ctime >= '2020-03-03 00:00:00' and ctime<= '2020-03-03 23:59:59' order by id desc limit 1800,100

由于这个表是个日志表,相当大,大约有十几亿条数据,翻页是很慢的,及时有ctime限制而且有索引,大约执行了几十秒,后续优化了一把。

2、第一次优化

我想优化方案是

1、取出今天的minid

2、 where id > minid order by id asc limt 100

3、取出上一步筛选出来最大的maxid, minid= maxid再次进入2循环取,直到取不到值为止

问题的关键在于minid开始初值我写的0,为0的话minid条件不命中,条件第二次才会有。造成的慢sql

select id,  mobile from sms where type='0' and status='0' and ctime >= '2020-03-04 00:00:00' and ctime<= '2020-03-04 23:59:59' order by id asc limit 100

这条sql的原因在于:ctime这个索引根本不起作用,直接用id进行扫描的,所以执行非常慢。

3、第二次优化

1、minid = select min(id) from sms where type='0' and status='0' and ctime >= '2020-03-04 00:00:00' and ctime<= '2020-03-04 23:59:59' 这个执行很快,ctime有索引

2、select id,  mobile from sms where id>minid and  type='0' and status='0' and ctime >= '2020-03-04 00:00:00' and ctime<= '2020-03-04 23:59:59' order by id asc limit 100

3、从2中结果取出mobiles放在内存中,同时取出这一批次中最大的maxid,   minid = maxid

再次循环2取数据,直到取不到为止,这个就顺利解决了

4、总结

对于大翻页,排序按照区间的最大id为条件,再去请求数据,这样能减少扫描的行数,从而减少sql执行时间。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章