MySQL調優

yetangjian發表於2022-05-21

概述:

通常情況下我們需要運算元據量較大的資料庫表時候,需要關注sql的開發規範、資料索引以及慢查詢

開發規範:

1 查詢sql都應該建立索引

覆蓋索引:(這裡我們先引用百度百科的解釋)覆蓋索引是select的資料列只用從索引中就能夠取得,不必讀取資料行,換句話說查詢列要被所建的索引覆蓋。索引是高效找到行的一個方法,但是一般資料庫也能使用索引找到一個列的資料,因此它不必讀取整個行。畢竟索引葉子節點儲存了它們索引的資料;當能通過讀取索引就可以得到想要的資料,那就不需要讀取行了。一個索引包含了(或覆蓋了)滿足查詢結果的資料就叫做覆蓋索引。優點:減少了回表時間

:主鍵索引:葉子節點儲存資料 ;輔助索引:葉子節點儲存主鍵值 (基於innoDB引擎)

我們這裡通過EXPLAIN語句查詢(留意EXPLAIN輸出的rows列,如果rows列太高,比如幾千,上萬,那麼就需要考慮是否索引不佳或連線表的順序不當)

 

 

 聯合索引 + 最左匹配原則 :(這裡引用知乎普及一下知識)

聯合索引:索引的底層是一顆B+樹,聯合索引同樣是一顆B+樹,只不過聯合索引的健值數量不是一個,而是多個,資料庫依據聯合索引最左的欄位來構建B+樹。

最左匹配原則:

聯合索引(A,B,C),最左優先,以最左邊的為起點任何連續的索引都能匹配上。

1)遇到範圍查詢(>、<、between、like)就會停止匹配。

2)因為Mysql中有查詢優化器,會自動優化查詢順序,因此A,B,C順序調換不影響查詢結果。

3)沒有從最左邊開始,最後查詢沒有用到索引,用的是全表掃描

這時候一定有小夥伴會問:沒看懂,這是啥啊?你以為我看懂了?我肯定也沒啊?但是沒關係,你只要記住為什麼要使用聯合索引,或者記住他的優點是什麼?

優點:a.建立一個聯合索引,相當於建立了多個索引(比如你建立一個(a,b)聯合索引,等於建立了a,(a,b)),這樣可以減少操作和磁碟空間的開銷;

    b.多索引會提高搜尋效率實現之前所說的覆蓋索引,減少回表

注:我們在使用GROUP BY、DISTINCT、ORDER BY,如果連線了多張表,ORDER BY的列應該屬於連線順序的第一張表,需要保證索引列和ORDER BY的列相同,且各列均按相同的方向進行排序

避免索引失效

索引會提高我們執行速度,但是有些操作會讓我們索引失效,所以我們要注意不能讓索引失效:

1.觸發了值型別轉換

2.對索引進行函式操作或者表示式操作

3.使用like進行了左模糊匹配或者左右模糊匹配 like "%##" ;like"%##%" (注:右模糊不會影響索引)

利用子查詢優化超多分頁場景

(這裡引用一下阿里巴巴JAVA開發手冊):MySQL 分頁並不是跳過 offset 行,而是取 offset +N 行,然後返回放棄前 offset 行,返回
N 行,所以當 offset 特別大的時候,效率就非常的低下,要麼控制返回的總頁數,要麼對超過特定閾值的頁數進行 SQL 改寫

簡單說我們應該用子查詢先把要查的範圍取出來,作為一個臨時表b

例如:select a.* from a , b where a.id = b.id

注:子查詢在效能上會比連線查詢差,所以能改成連線查詢儘量改成連線查詢。

事務隔離

這一部分我自己也不是很瞭解,最近出了一次生產事故所以特意去做了大致瞭解。大致介紹一下背景,我是個測試小羅羅,我們公司屬於物聯網公司,在邊緣端本地工控機會存放比較大量的本地資料,但是受限於工控機的配置較低所以需要定期做資料清理,就是用定時任務去刪除一些無用資料。接到這個測試任務的時候,我對資料庫事務這塊基本沒有了解,所以用例的覆蓋並沒有併發操作。上線後第二天早上就接到告警電話了,一個大型工廠使用受限,cpu已經達到90%降不下來了,主要佔比就是mysql。

覆盤:本次優化的sql語句因為使用了多表連刪,(這裡需要特別提一句,MySQL連線(JOIN)嚴重降低了併發性,對於高併發,高效能的服務,應該儘量避免連線太多表,如果可能,對於一些嚴重影響效能的SQL,建議程式在應用層就實現部分連線的功能)雖然有部分回表但基本索引是走的沒問題的,但是因為我們使用的是mysql的預設事務Repeatable read(可重複讀),在刪除語句事務執行時候上了行鎖+間隙鎖,併發的插入語句修改語句被鎖,因為資料量很大導致瞬間cpu飆升,最終導致影響工廠生產。

總結:如果有了解到你們資料庫隔離級別走的是 可重複讀 (REPEATABLE READ)一定要注意了!只有在可重複讀的隔離級別下,才會有間隙鎖。間隙鎖可能會造成死鎖!

慢查詢

當索引解決不了慢查詢時,一般由於業務表的資料量太大導致,可以考慮走redis或者增加檢視查詢

當讀寫效能均遇到瓶頸時,升級資料庫架構或者考慮分庫分表

相關文章