背景
先是收到系統(tǒng)警告信息數(shù)據(jù)庫連接超過了2600,接著就收到客戶反饋系統(tǒng)進(jìn)不去,大量的數(shù)據(jù)庫報(bào)錯(cuò),‘SQLSTATE[HY000] [2002] Connection timed out:。。。’,第一反應(yīng)就是數(shù)據(jù)庫被查爆了;
快速解決方案
為了使系統(tǒng)快速恢復(fù)正常,于是選擇重啟數(shù)據(jù)庫,釋放掉數(shù)據(jù)庫連接數(shù),再去追蹤和分析數(shù)據(jù)庫慢查詢?nèi)罩?;重啟完?shù)據(jù)庫系統(tǒng)恢復(fù)了正常,但是監(jiān)控到慢查詢還在不斷的產(chǎn)生,于是快速定位相關(guān)的業(yè)務(wù),發(fā)現(xiàn)是定時(shí)任務(wù)產(chǎn)生的,于是暫停掉了該定時(shí)任務(wù),數(shù)據(jù)庫再次重啟后恢復(fù)了正常(第一次重啟后又產(chǎn)生了很多慢查詢);
分析慢sql
等系統(tǒng)恢復(fù)正常后,可以慢慢分析那條最慢的sql了,執(zhí)行時(shí)間是1432秒,貼上這條慢sql:
explain
SELECT
creative_id,
`advertiser_id`,
`subaccount_id`,
create_time,
update_time
FROM
`originly`
WHERE
`advertiser_id` = 2000
AND `subaccount_id` = 63005
AND `creative_type` = 2
ORDER BY
creative_id ASC
LIMIT
1;
咋一看這條語句還limit 1 了居然還會(huì)這么慢, 而且這個(gè)originly表也不是特別大,大概也就4百多萬數(shù)據(jù);于是使用explain 工具查看了下索引使用情況:

發(fā)現(xiàn)只使用了creative_type索引,前面那個(gè)advertiser_id和subaccount_id 并沒有索引,目前表的索引情況如下:
PRIMARY KEY (`__ID__`),
UNIQUE KEY `creative_id` (`creative_id`),
KEY `creative_type` (`creative_type`),
KEY `is_template` (`is_template`),
KEY `advertiser_id` (`advertiser_id`,`ad_id`,`creative_type`) USING BTREE,
KEY `unique_creative` (`advertiser_id`,`ad_id`,`creative_name`) USING BTREE,
KEY `create_time` (`create_time`)
由于creative_type 的值也就那么幾種,需要篩選的數(shù)據(jù)量仍然很多,所以即便是有這個(gè)索引,對(duì)于大表來說作用很小了,于是想單獨(dú)在advertiser_id 或者 advertiser_id + subaccount_id 建立索引,筆者先是試了下單獨(dú)在advertiser_id 上建立索引,發(fā)現(xiàn)效果不明顯(應(yīng)該是還得在一個(gè)大的數(shù)據(jù)集里面篩選匹配的operator_subaccount_id)于是選擇在advertiser_id + subaccount_id建立組合索引,運(yùn)行效果發(fā)現(xiàn)這個(gè)查詢很快就有了結(jié)果:

總結(jié)
(1)其實(shí)上面這條語句在一開始并不是一個(gè)慢查詢,主要是隨著數(shù)據(jù)量的增多變成了慢查詢,所以在實(shí)際開發(fā)中我們需要考慮隨著數(shù)據(jù)量的增大,我們寫的sql是不是最優(yōu)的;
(2)通過以上案例得出一個(gè)sql優(yōu)化思路,我們需要在我們的查詢條件的字段上加索引,當(dāng)然加索引會(huì)影響到數(shù)據(jù)庫寫入的速度,所以我們需要結(jié)合業(yè)務(wù)對(duì)一些經(jīng)常查詢的業(yè)務(wù)場景做分析然后創(chuàng)建合適的索引;
好了,今天就到這里了,希望對(duì)小伙伴們有所幫助,后面還有一些關(guān)于慢查詢的優(yōu)化;