MySQL占用CPU超過百分之100解決過程


本文轉載自: https://www.93bok.com

訪問網頁504 Gateway Time-out,登陸服務器查看,內存正常,CPU使用率達到了400%,因為是4核,所以到了400%,幾乎全部滿負載在跑了,又在下圖中發現,單單一個mysqld的進程,就占了390%,毫無疑問,數據庫的問題導致了網頁504。

1、使用top看到的情況如下

isoa7D.png

2、登陸數據庫,輸入show full processlist;可以看到正在執行的語句

isowAe.png

可以看到是下面的SQL語句執行耗費了較長時間:

SELECT id,title,most_top,view_count,posttime FROM article where status=3 AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17)  order by most_top desc,posttime desc limit 0,8

還可以從show full processlist命令中得出下圖中的端口號,我們也可以使用netstat -anupt | grep 端口號查看一下是什么進程打開的這個MySQL連接,這里我就不演示了,你們可以自己嘗試排查一下問題。

isor9A.png

3、但是從數據庫設計方面來說,該做的索引都已經做了,SQL語句似乎沒有優化的空間。

直接執行此條SQL,發現速度很慢,需要7-8秒的時間(跟mysql正在並發執行的查詢有關,如果沒有並發的,需要1秒多)。如果把排序依據改為一個,則查詢時間可以縮短至0.01秒(most_top)或者0.001秒(posttime)。

4、通過EXPLAIN分析這條SQL語句
EXPLAIN SELECT id,title,most_top,view_count,posttime FROM article where status=3 AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17)  order by most_top desc,posttime desc limit 0,8

iso6jP.md.png

可以看到,select對45萬條記錄使用filesort進行排序,這是造成查詢速度慢的原因。

5、優化

首先是縮減查詢范圍

SELECT id,title,most_top,view_count,posttime FROM article where status=3 AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17)  and DATEDIFF(NOW(),posttime)<=90 order by most_top desc,posttime desc limit 0,8

發現有一定效果,但效果不明顯,原因是每條記錄都要做一次DATEDIFF運算。后改為

SELECT id,title,most_top,view_count,posttime FROM article where status=3 AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17)  and postime>='2017-09-05' order by most_top desc,posttime desc limit 0,8

查詢速度大幅提高。

6、效果

查詢時間大幅度縮減,CPU負載很輕,頁面恢復正常

iso2B8.png

iso4hj.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM