圖
文
單表優化
欄位設計
單表不要有太多欄位;
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 協議》,轉載必須註明作者和本文連結