MySQL 資料過多時的優化--圖文並茂版

alalala發表於2020-03-31

MySQL資料過多時的優化

單表優化

欄位設計

  • 單表不要有太多欄位;

  • VARCHAR 的長度儘量只分配真正需要的空間;

  • 儘量使用TIMESTAMP而非DATETIME;

  • 避免使用NULL,通過設定欄位預設值來解決;

  • 儘量符合三正規化設計。

    • 第一正規化(1NF):表的列具有原子性,不可拆分,只要是關係型資料庫那麼就自動符合第一正規化(1NF)的要求;

    • 第二正規化(2NF):滿足第二正規化必須先滿足第一正規化,確保表中每一列都和主鍵有關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。也就是說在一個資料庫表中,一個表中只能儲存一種資料,不可以把多種資料儲存在同一張資料庫表中;

      • 表必須有一個主鍵;

      • 沒有包含在主鍵中的列必須完全依賴於主鍵,而不能只依賴於主鍵的部分。

    • 第三正規化(3NF):滿足第三正規化的必須先滿足第二正規化,目標是確定其他非主鍵列都是與主鍵列直接相關而不是間接相關,非主鍵列必須直接依賴於主鍵,不能存在傳遞依賴。

索引優化

  • 要針對性的建立索引,索引會加速查詢,但是對新增、刪除、修改會造成一定的消極影響;

  • 值域很少的欄位不適合建索引,比如使用者表的性別,;

  • 儘量不用唯一索引,不建外來鍵,使用程式保證。

  • 正確的使用索引:

    儘量使用索引,但是需要保證避免錯誤地使用導致的索引失效問題 :

    • like 以%開頭,索引無效;當like字首沒有%,字尾有%時,索引有效;

    • or語句前後沒有同時使用索引,當or左右查詢欄位只有一個是索引,該索引失效,只有當or左右查詢欄位均為索引時,才會生效;

    • 組合索引,不是使用第一列索引,索引失效;

    • 資料型別出現隱式轉化,如varchar不加單引號的話可能會自動轉換為int型,使索引無效,產生全表掃描;

    • 在索引列上使用 IS NULL 或 IS NOT NULL操作,索引是不索引空值的,所以這樣的操作不能使用索引,可以用其他的辦法處理,例如:數字型別,判斷大於0,字串型別設定一個預設值,判斷是否等於預設值即可;

    • 在索引欄位上使用not,<>,!=,不等於操作符是永遠不會用到索引的,因此對它的處理只會產生全表掃描, 優化方法: key<>0 改為 key>0 or key<0;

    • 對索引欄位進行計算操作、欄位上使用函式;

    • 當全表掃描速度比索引速度快時,mysql會使用全表掃描,此時索引失效。

善用NoSQL

有一些場景,可以拋棄 MySQL 等關係型資料庫,擁抱 NoSQL,比如:統計類、日誌類、弱結構化的資料;事務要求低的場景。

增加快取

主要思想就是減少對資料庫的訪問:MySQL本身就支援快取,只不過在MySQL 8.0版本中被取消了;第三方的快取,如 Redis 的快取。

表分割槽

MySQL 在 5.1 之後才有的,可以看做是水平拆分,分割槽表需要在建表的時候加上分割槽引數。

表拆分

  • 垂直拆分

    垂直拆分就是將一個欄位較多的表,拆分成多個欄位較少的表,一般來說,單個表的欄位數不宜超過二、三十個;

  • 水平拆分

    • 分庫分表:分表,解決了單表資料過大的問題,但是畢竟還在同一臺資料庫伺服器上,所以 IO、CPU、網路方面的壓力,並不會得到徹底的緩解,這個可以通過分庫來解決。

    • 水平拆分優點很明顯,可以利用多臺資料庫伺服器的資源,提高了系統的負載能力;缺點是邏輯會變得複雜,跨節點的資料關聯效能差,維護難度大(特別是擴容的時候)。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章