mysql調優三部曲 SQL優化三步曲

2021-10-19 15:47:26 字數 2171 閱讀 9920

有一天開發同學反饋線上業務庫中有一條sql執行很滿,每次幾乎要跑1分鐘才結束,希望我們幫忙優化一下,具體sql如下:

sql優化第一步 - 檢視執行計畫

對於乙個sql的優化,我們的第一步也是最重要的一步就是檢視sql執行計畫,sql執行計畫一方面告訴我們sql具體的處理行為,另外一方面也可以體現每個執行步驟下大致的資源消耗點。所以我們拿到問題sql以及對應資料庫環境後,登入該環境唯讀例項進行sql分析測試。

從以上的sql執行計畫我們可以獲取到哪些有效資訊呢?

sql先對t表掃瞄查詢生產派生表,brand通過索引過濾作為表關聯的驅動表,與vender、product、shop_product、spu、進行關聯查詢,表關聯均有效利用索引。

從type欄位上看,sql基本上都有效利用到了索引,但是index其實是全索引掃瞄,該方式的索引掃瞄執行效率並不會很好

對t表的index全索引掃瞄資料量高達480w,在當前sql中執行消耗最大,這也將是我們sql優化的切入點

t表在源sql中並未出現,再次仔細觀察sql可以發現sql引用了view_prod_store_sum的檢視

sql優化第二步 -

在mysql中對於檢視使用我們需要知道的是雖然mysql對檢視的查詢做了一些優化,但是對於複雜檢視查詢其優化支援仍然不是很好,所以業務上我們要盡量避免對複雜檢視的使用。在本sql中檢視其實是對單錶的查詢,且目前sql資源消耗的瓶頸點也在檢視查詢這部分,所以我們將檢視的定義通過子查詢代替原檢視,整體的來看sql。

檢視定義:

完整sql:

sql優化第三步 - 適當改寫

結合我們獲取到的sql執行計畫以及恢復出來的完整sql,我們再次理解當前sql的處理行為:

1)對t表進行全索引掃瞄,生產派生表2

2)brand表通過brand_id in (252)條件進行索引過濾,後續與其他表以及派生表2進行關聯查詢

資源消耗點分析:

從sql真正需要查詢的資料來看,我們只需要先通過where子句中表過濾條件過濾獲取初步滿足條件記錄,然後對這些記錄判斷 sum(store) > 0是否滿足,滿足則返回。但是該sql實際處理卻是先將t表中所有記錄的store進行分組計算,將結果儲存在派生表中。通過where子句中表過濾條件後的記錄再與派生表關聯判斷sum(store)。

sql在處理的過程似乎掃瞄了很多不必要的資料,我們為何不僅僅對已滿足where子句條件過濾的記錄做sum(store)判斷呢?

基於以上的分析,我們嘗試使用exists相關子查詢進行改寫測試。為什麼使用相關子查詢呢,這是因為exists在處理sql時的核心思想是先對where 前的主查詢詢進行查詢,然後用主查詢的結果乙個乙個的代入exists的查詢進行判斷。 因此我們可以有效的利用exists避免的避免掉優先對t表的派生表產生,保證sql優先通過where子句中選擇性最佳的條件做驅動表,然後對sum(store)通過相關子查詢進行判斷。

具體改寫如下:

改寫後的執行計畫:

執行效率對比

優化前:

優化後:

在一般業務sql編寫中,我們都推薦開發同學使用join而不是exists,這是因為exists本身處理sql的方式下如果where條件處理後外表記錄仍然很大的情況下,再次將外表中每條記錄代入exists子查詢中判斷,其資源消耗代價是很大的。所以我們更偏向使用join,在滿足必要的索引情況下mysql優化器優先選擇小表進行驅動。無論具體選擇什麼方式,其實減少掃瞄函式才是王道!

人生三部曲

人生三部曲 童年沙丁魚罐頭似的公共汽車在曬的發燙的柏油路上緩慢地爬著。我 瘦瘦小小的個子在擁擠的人群中喘不過氣來。還要多久呀?人們煩躁而沉悶的氣氛充斥著整個車廂。忽然,我看見一位打扮入時的西裝人士,正悄悄地把手伸入一位老人的口袋。我第一反應就是有小偷!於是大聲脫口而出,一車人都回頭驚悸地看著我,西裝...

Jmock使用三部曲

import org.jmock.mockery import org.jmock.expectations class publishertest extends testcase execute publisher.publish message verify assert.assert.注意 ...

SoftwareRender三部曲 前言

這個系列主要是介紹如何簡單製作乙個softwarerender,後面會分三篇文章來完成這個系列。在看這個系列之前最好先閱讀之前 遊戲開發3d數學筆記 在這個工程中的所需要的一些數學庫 vector matrix mesh等 都 於之前3d數學系列。當然,這些數學庫使用上比較簡單,如果你對其數學原理不...