1. 程式人生 > >MYSQL "ORDER BY rand()"的坑--容易導致機器負載、CPU佔用過高

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)之類的,網上可以查到這方面的許多材料,就不多說了。最後感謝專業運維好兄弟 瑞哥 的幫助!希望此篇教程可以幫到遇到類似問題的小夥伴。