今天上午十點(diǎn)后,公眾號服務(wù)器突然崩潰,查詢?nèi)罩景l(fā)現(xiàn),是由于一條查詢語句超時(shí),導(dǎo)致CPU使用率飆升到80+,
下面記錄下問題,及解決方案,
SELECT * from hb
WHERE progress = 'A'
AND hb_whether_big = 0
AND platfrom = 'meituan'
ORDER BY which_is_big - current_num
LIMIT 1;
??這條SELECT語句,主要是ORDER BY子句中的which_is_big - current_num
,導(dǎo)致了查詢速度緩慢,其次沒有及時(shí)把過期的記錄(紅包)排除在外,再加上上午的高峰期,引起了這次故障的發(fā)生.
故障發(fā)生后,
首先將定時(shí)執(zhí)行的job表中的未執(zhí)行的數(shù)據(jù)進(jìn)行了清空,稍微減輕服務(wù)器負(fù)擔(dān),避免網(wǎng)站掛掉,然后查閱日志,迅速定位到故障位置后,暫時(shí)先將ORDER BY子句刪除(短期去除對業(yè)務(wù)影響不大),服務(wù)暫時(shí)恢復(fù)正常,最后對語句先后進(jìn)行如下優(yōu)化:
## 分別排序會先對第一個(gè)字段進(jìn)行排序,排好后,在其基礎(chǔ)上,再對第二個(gè)字段進(jìn)行排序
## 這樣執(zhí)行效率雖然可以接受,但是和最初的字段相減的邏輯有出入
SELECT * from hb
WHERE progress = 'A'
AND hb_whether_big = 0
AND platfrom = 'meituan'
ORDER BY which_is_big, current_num DESC
LIMIT 1;
最后采用了下面這種寫法
## 先將計(jì)算結(jié)果查詢出來,臨時(shí)命名一個(gè)d_value字段表示差值,然后對這個(gè)字段進(jìn)行排序,達(dá)到了和最初邏輯一樣的效果
## 并且新加入了一個(gè)ctime將數(shù)據(jù)范圍限制在了一周內(nèi)
SELECT *,(which_is_big - current_num) as d_value
FROM hb
WHERE progress = 'A'
AND hb_whether_big = 0
AND platfrom = 'meituan'
AND ctime>''
ORDER BY d_value
LIMIT 1;