MySQL limit分页的一次优化 - Go语言中文社区

MySQL limit分页的一次优化


      昨天临近7点,手头的活干完了,心里美滋滋的。想着今天可以提前下班了,晚上回去干些什么呢。。。。。这时候,QQ弹出老大发我的消息:你上次写的JOB脚本中,出了点问题!当时第一反应就是,What?程序都运行得好好的,怎么会有问题呢!退一万步说,即使出现线上报错,也应该看到报错日志!(PS:作为一个立志要成为大神的开发工程师来说,怎么允许自己的线上代码出问题!)老大不说话,抛出了一个SQL语句:
在这里插入图片描述
     看到这个语句, 第一反应,没啥问题啊!再仔细看,what,执行时间为啥这么慢???于是就有了今天的这篇文章。
      首先说下这个JOB程序的背景:表里面存放着历年来的注册电话号码(当然是进行加密过了的!),现在需要对这些加密的电话号码先还原成真实的电话号码,然后用另外一套算法进行加密,目的是统一公司的电话号码加密方式,方便BI那边集中处理。其实吧,这个需求除了加密算法要重写(简单的说,就是阅读加密算法的JAVA实现版本,用PHP来实现)有点挑战性外,其它部分根本就没啥难度,主要做法就是:一次批量读取500-100条数据,然后用加密算法批量处理,然后插入到数据表里面即可,这个过程中,控制读写的频率即可(防止高频率大批量读写数据表对线上业务造成影响)!最后完成任务,测试OK,上线!在这里,查询表,主要使用语句

SELECT * FROM table  LIMIT 500 offset rows

     主要就是从"table"表中读取500条数据,偏移量是rows。在测试的时候,这样没啥问题,然后执行效果也挺好的。但是上线后,问题就来了:主要是,这个表里面的数据量实在是太多了
在这里插入图片描述
      有5000多w条数据!我把老大发我的那个语句拿到表里面去执行了下:

  • List item

在这里插入图片描述
     执行时间竟然要2s多!我勒个去,这还只是百万级别,那如果到了千万级别呢?我尝试着在表里面执行了下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2019030914355581.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3docTE5ODkwODI3,size_16,color_FFFFFF,t_70
     差不多10s!要知道我有5000多w条数据要处理呢!如果按照10s来估算,差不多得5000000秒!(约58天)
     作为一个要立志成为大神的人来说,这个问题不能容忍!于是停止线上JOB的运行,开始想办法解决这个问题。然后就发现,要解决这个问题其实很简单:表里面有id,利用id的自增方法来代代替limit offset的这种方式。在表里面尝试了下,按照相同的方式查询:
在这里插入图片描述
      最后约为0.0053s!相差大概是2000倍的差距!问题找到了,解决方法也就随之而来!最后仅用了40多个小时JOB就处理完了所有的数据!PS:代码执行的效率在数据量小的时候,可能看不出来,但是当数据量或并发量很大的情况下,效率低的代码就容易成为性能瓶颈!看来,成为大神之路还很漫长啊!
总结如下:
优化前:

SELECT * FROM `table` WHERE  id > 0 LIMIT 500 OFFSET 3057000;

优化后:


SELECT * FROM `table` WHERE  id > 3057000 LIMIT 500 

微信公众号来源


    欢迎大家关注我的微信公众号,会分享自己在Web开发领域和生活工作中的一些所思所悟,希望能给你带来帮助!
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/whq19890827/article/details/88365909
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-07 21:01:12
  • 阅读 ( 1297 )
  • 分类:数据库

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢