每日踩坑 2022-01-11 記一次MySQL索引優化引發的思考

上午正在給領導上線東西看效果,然後客戶羣裏就突然開始說有查詢特別慢,之前也沒反映過。

可能是因爲前一段時間公司優化(壓縮成本)了一些數據庫的配置。

 

同樣的一個查詢,某些參數不同,查詢時間卻翻了好幾倍。

看日誌是數據庫鏈接斷開了,崩潰性錯誤。

Fatal error encountered during command execution.

後來知道這個應該是阿里雲RDS設置的30s自動斷,防止慢查詢影響整個庫的性能。

然後我就開始查,這查詢我明明寫的時候速度可以的。

然後手動從本地抓了最終執行的SQL語句,但這裏有個關鍵,我忘記加上後跟的Order語句了,我複製完到正式環境數據庫一執行,發現是秒出,想想客戶反應也是,有些查詢不慢,有些慢的一匹。

這裏其實也是漏掉了一個關鍵信息,查詢中的時間區間,這一點我們前端提醒我了,但是我給否定了。

 

各種排查嘗試,甚至我還看了阿里雲RDS的性能監控,還看了IIS的線程,因爲上面漏掉Order,使我認爲問題是出在站點上,所以還花了時間排查服務器和代碼更改記錄。

但是各種嘗試都沒用,仔細想想日誌中說明問題還是出在數據庫,確確實實查詢數據量大或者慢查詢了。

然後我又抓了遍執行sql,這次是用調試工具抓的,這一抓看見Order By我就知道完了,指定是它的問題。

然後直接Mysql裏看一下EXPALIN,好傢伙,索引選到了Order的字段單個索引,其實是一個數據修改時間。用了1m的時間纔出結果,五百萬單字段索引查詢用了一分鐘,感覺還是有點拉跨。

這裏我直接把這單個字段的索引刪掉就可以了,mysql又自動選擇了一個多業務字段複合的索引,自然是秒出了。

這個表目前的數據量是五百萬級別,每天新增的數據量會比較穩定,大概在五萬左右。30+字段,已經有十來個索引了。幾乎是不敢動的狀態,只能任由它凌亂下去。

 

索引優化有非常多的困難。通常來說對於一個線上的數據庫,沒辦法隨時調整索引,而且開發沒有辦法對索引的調整有所感知,調整之後會不會影響其他查詢?會不會越調整越凌亂?這些都是問題。

 

之前剛來這公司的時候就在想究竟該怎麼去優化,治理索引。

 

實際上在我看來,大多數時候,如果表的結構設計合理,一開始對於數據規模的估算和設計比較合理這都不會造成之後嚴重的性能問題。當然,這是理想主義。產品經理總會在適當的時候打破你的幻想。

我接手的代碼中存在很多在查詢語句中指定使用索引。這顯然僅僅是一種應急的解決方法。

這種做法會帶來一些問題,

一是代碼的維護問題,代碼中不具備對索引使用的框架級支持,這意味着維護上的問題。

二是通過硬編碼的方式指定索引,這會帶來各種環境的問題,因爲一旦索引不存在或者配置了錯誤的編碼。會導致直接報錯。查得慢一些總是比報錯強。

三是通過這種方式對一些查詢使用特定索引,會導致索引數量膨脹凌亂。參與開發的人員如果較多就難以控制。而且索引加多了也會導致更新與插入速度變慢,

對於大多數業務複雜的系統來說都很難接受(譬如我們現在這個)我們現在的插入速度已經相當慢了,用戶可感知的卡頓。

 

綜上所述,這幾個問題已經指出了一個理想化的方案就是框架級可以對索引進行管理。

這個框架級應該具備至少以下的能力:

  • 通過對代碼中或運行時的SQL語句分析可以給出建議索引甚至自動創建索引。
  • 可以在執行sql時動態選擇索引(比弱智mysql引擎更好的選擇方法

事實上想到這裏我已經發現了我對標的不就是數據庫治理嗎,之前去聽2021數據庫大會的時候沒少聽那些廠商談論這個。

這些功能大多數的數據管理工具和阿里雲RDS上都有。對於開發人員來說,最好的當然還是基於自己的代碼中去實現,省時省力可定製,否則又是徒增複雜度而已。

 

至於我要不要實現這個東西,思考了一下複雜度和可用性之後我選擇放棄。

主要是沒時間(lan)。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章