MYSQL "ORDER BY rand()"的坑--容易导致机器负载、CPU占用过高

在一次微信砍价活动营销中,使用了4核16G10M带宽的服务器支撑业务,本来这个配置跑个PHP+MYSQL+nginx肯定轻轻松的事情,可是随着活动的高潮,并发数一高,机器负载核CPU一下子就达到100%

始终找不到原因,只知道是mysql分配的内存不够,一直给它加,但是重启mysqld服务之后不久又会再次出现负载100%,页面加载龟速的问题。后来通过SQL分析找到了问题:

分析:

执行语句:show full processlist; 显示哪些线程正在运行。

上面是个列表,我只截有问题的语句,大家可以把正在执行的线程具体语句都抓出来排查

这句话完整sql语句是

    $sql = " SELECT * FROM ".tablename('mc_mapping_fans')."  ORDER BY rand() LIMIT 3 ";

然后再分析它

EXPLAIN  SELECT * FROM `ims_mc_mapping_fans`  ORDER BY rand() LIMIT 3;

可以看到为什么它会卡,涉及的行列有60000多行,随机取3个结果出来,我是每个页面点进去都随机抓3条出来展示,而且是3秒一次,这有肯定会造成服务器卡死!

问题找到了,赶紧做测试,把语句由

    $sql = " SELECT * FROM ".tablename('mc_mapping_fans')."  ORDER BY rand() LIMIT 3 ";

改为

    $sql = " SELECT * FROM ".tablename('mc_mapping_fans')."  LIMIT 3 ";

去掉ORDER BY rand(),保存。

再看CPU、负载情况:

一片健康的指标,问题终于解决了!修改保存后可看到宝塔面板里的负载、cpu使用率噌噌往下降。

结尾:ORDER BY rand() 在查询范围大的情况下会增大服务器负载和增大查询时间,不要轻易使用,可以采取其他随机函数,比如select max(id)之类的,网上可以查到这方面的许多材料,就不多说了。最后感谢专业运维好兄弟 瑞哥 的帮助!希望此篇教程可以帮到遇到类似问题的小伙伴。

猜你喜欢

转载自blog.csdn.net/yymgary/article/details/84327198