SQL 調優三板斧,拿好拿穩了

  • 2019 年 12 月 2 日
  • 筆記

前言

大家都知道,至少老讀者應該都知道,我是從網管,編程,DBA,數倉一路爬過來的。這麼多年的風裡雨里多少有些技術上的技巧可以分享給大家。還記得有個曾經抖落過一段小插曲嗎,發生在網管裝機那個時代。

裝機對於那個年代來說,其實沒有太大的懸念。但外行看着還是覺得很高深。我們拿出螺絲刀,把風扇,CPU,內存,硬盤拔下來的瞬間,大家都是覺得不可思議的。我能感覺到他們的心疼,畢竟一台PC還要7,8000的時候,被我這麼折騰,還是心有餘悸。

但是我們老手都知道,洗手,拆箱,插拔,只要不帶電操作,安全得很。甚至只要聽到BIOS(年輕人估計都不知道了吧)的三長兩短聲,立馬可辨,是內存,還是硬盤有問題了。拆裝到位,一擊即中。

上面是硬件部分的維護,那到軟件部分怎麼樣呢?網上不去,軟件卡了,黑屏,藍屏?套路與硬件故障排除一樣,重插網線,重啟電腦(萬惡的Windows 98),卸載軟件重裝,最後萬靈的一招,PE重裝系統,Ghost 備份!

現專註於數據庫開發了,碰到性能有問題,其實和硬件故障排除並沒有多大區別,也有個套路。鑒於我們SQL微信群新朋友的疑惑,沒怎麼讀我以前的文章,所以不知道我曾經寫過「SQL調優三板斧」,這裡我就重提一下。

第一板斧

跟上不了網一樣,第一件事情,大家會做什麼?對,就是檢查網線。

SQL查詢太慢,你會做什麼?肯定不是去看網線了,網線一斷,你的SQL直接報timeout錯誤了,根本不給你往下執行的機會。

SQL查詢太慢,我們要做的事情當然是去檢查,當前的SQL是不是在跑?還是在等CPU中央司令員給你機會去跑。數據庫有自己的任務分配系統,如果你的線程級別比較低,分配系統就不給你機會去執行,那也白搭。那就只能等着了。

同學可能不知道為什麼要等待,而不是發完SQL就立即執行這個概念!

舉例,如果我們的數據庫有分佈式的應用,比如讀寫分離,那麼在系統正在執行讀寫分離的時候,會有大量的任務在跑,而且級別較高,佔用的服務器資源就會很多,比如高CPU,高內存,高IO.這個時候,任何的查詢都會被掛起,只有等待CPU/Memory/io的分配,才能 運行。

第二板斧

平時大家都是寫 CRUD 的任務多,很少有人會去看數據庫的實現代碼。所以很多細節不會清楚。但很多廠商為我們做好了可以瞥一眼神秘的數據庫引擎實現的地方,那就是 execution plan(執行計劃).

在執行計劃中,我們可以看到數據到底存儲在哪個硬盤位置,內核是如何讀取這些硬盤位置的數據,數據加載到內存後,又經過什麼算法來得到我們想要的計算結果。

這些數據庫本身的內核代碼及實現,都源於IBM的一篇論文(大家在關注本號的時候,都應該拿到這篇論文了).

知道這篇論文非常重要,它能幫你理解,整個數據庫至少引擎部分,是怎麼工作的。結合各個數據庫軟件的執行計劃,你就會知道計劃的哪個部分,有很大的提升空間。再評估使用哪個手段去提升它。

第三板斧

第三板斧,有些深入細節了。運行時統計信息的採樣分析。

我們從IBM的論文中,可以得到這麼個啟示。很多引擎的算法都得益於採集到的元數據統計信息。基於這些信息,引擎會自動選擇最優的算法。

比如一張表的Country字段(存儲國家信息),經過統計,只有3個國家,中國,美國,歐盟。其中包含中國的記錄數佔據了85%的數據,而其他兩國都只有7%,8%的數據。

如果有查詢需要查詢包含中國相關的數據,那麼採用全表/全索引掃描的方式會快很多,因為回表這部分(如果不知道回表,可以往前翻翻我的文章)的成本就被極大的節約了。一旦查詢其他兩國,那麼使用索引搜索更快。你發現某個查詢在查詢包含中國相關數據時,執行計划走的是 index seek, 你就可以幫執行計劃調整成 index scan 或者table scan了。(同樣,如果不知道怎麼調執行計劃,可以翻翻我之前的文章)

結尾

總結下來,就是檢查等待,分析執行計劃,運行時統計信息採集。如果能從這三個方面去分段調試,肯定能找到80%的性能問題。