喂?xxx嗎?大家的服務怎麼回事,機器又掛掉啦~!
啊?掛掉幾臺了?
大家借的40臺掛了兩臺啦!
騷等,我看看咋回事!mysql
服務器又冒煙了~~~緣由是這樣的:sql
前段時間項目迎來七夕高峯,有一個接口的SQL原本長這樣:數據庫
mysql> explain SELECT *,sum(num) AS sum FROM search WHERE search_time >= '2016-08-30' AND type = 0 AND state = 1 GROUP BY keyword ORDER BY sum DESC LIMIT 50; +----+-------------+-----------+------+--------------------------+------+---------+-------+--------+----------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+------+--------------------------+------+---------+-------+--------+----------------------------------------------+ | 1 | SIMPLE | search | ref | type,search_time,keyword | type | 2 | const | 651114 | Using where; Using temporary; Using filesort | +----+-------------+-----------+------+--------------------------+------+---------+-------+--------+----------------------------------------------+
search_time
,type
,state
都建了索引,type
和state
取值範圍有限,因此基本沒啥用,主要是靠search_time
,可是explain
的結果表示並無用到有效索引,實際狀況下表裏有130w+
數據的時候這個語句跑起來平均耗時5s
多,這確定是不能忍受的。緩存
那強制索引怎麼樣?試試看:服務器
mysql> explain SELECT *,sum(num) AS sum FROM search FORCE INDEX (search_time) WHERE search_time >= '2016-08-30' AND type = 0 AND state = 1 GROUP BY keyword ORDER BY sum DESC LIMIT 50; +----+-------------+-----------+-------+---------------------+-------------+---------+------+--------+---------------------------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+-------+---------------------+-------------+---------+------+--------+---------------------------------------------------------------------+ | 1 | SIMPLE | search | range | search_time,keyword | search_time | 4 | NULL | 290616 | Using index condition; Using where; Using temporary; Using filesort | +----+-------------+-----------+-------+---------------------+-------------+---------+------+--------+---------------------------------------------------------------------+
有效果,rows
降到29w
,照理說在29w裏面怎麼查都不會太慢,可是都知道explain
裏的rows
只是個參考,實際跑起來仍是花了3s
多,也是不能忍受的。併發
這臺數據庫的機器同時還跑其餘業務,都是量級較大的,服務器負載原本就不低,七夕還沒到,就由於這條sql把服務器搞的直冒煙,本業務慢查詢也拖慢了其餘業務的執行時間致使連鎖反應。高併發
以前已經對數據的讀取部分加了緩存,可是日誌記錄仍是顯示某段時間內產生大量的慢查詢請求。開始咱們懷疑是緩存失效,但後來發現,實際上是高併發致使在設置緩存階段,因爲sql語句執行時間太長,致使在這5秒內形成大量數據庫慢查詢。日誌
直接說解決方案吧:code
縮小查詢範圍,由以前的查詢3天
改成查詢1天
,量級降到130w+
數據。blog
強制使用索引,必定程度上縮短查詢時間。
寫個腳本,定時將查詢結果保存到memcache
裏,這個主要是防止高併發狀況下,等待寫入mc時形成短期大量數據庫訪問。
對數據庫讀取結果作緩存。
對接口結果作緩存。
作了這5步工做,媽媽不再用擔憂個人服務器會冒煙啦~~
注:後面會慢慢把其餘blog移到這裏來,之後主要在這寫啦。