-
MYSQL瓶頸及應對措施
1)增加MYSQL配置中buffer和cache的數值,增加伺服器CPU數量和記憶體大小,這能很大程度上應對MYSQL的效能瓶頸,效能最佳化中效果最顯著成本最低的當屬硬體和伺服器最佳化,就優先考慮;
2)使用第三方引擎或衍生版本;
3)遷移到其他資料庫;
4)對資料庫進行分區、分表操作,減少單表體積;
5)使用NoSQL等輔助解決方案,如Memcached,Redis;
6)使用中介軟體做資料拆分和分布式部署;
最後,一個工具能不能用好,人的因素占很大的比重。
-
資料庫設計
(1)範式與反範式:為規範DB設計在DB理論發展的過程中,逐漸形成了DB範式的理論,到目前為止有五大範式。到了第三範式通常已經能夠滿足業務需求了,表之間的關係也比較清晰容易維護。
(2)反範式的提出:範式理論在20世紀70年代提出並在80拆借基本定型,那時候的系統的特徵為:可用的儲存空間資源極其有限,並且網路不成熟能使用網路的人較少通常只涉及單機的計算效能,所以範式理論強調減少依賴/降低冗餘;但現在內在廉價儲存不再是問題同時面臨高並發商務邏輯複雜低延遲的要求,所以不應一味遵循範式設計理論,應當適當降低範式,增加冗餘以空間換時間是值得的,最低可降至第一範式。
(3)通常在設計資料庫時需遵循以下原則:
1)核心業務使用範式。
2)弱一致性需求--反範式
3)空間換時間
4)避免不必要的冗餘
-
資料庫分區
所謂分區就是把一個資料表的檔案和索引分散儲存在不同的物理檔案中,MySQL5.1以上版本才支援分區。可用SHOW VARIABLES LIKE ‘%partition%’來確認是否支援分區。MYSQL支援的分區類型包括Range/List/Hash/Key,其中Range最常用,樣本:
CREATE TABLE foo (id INT NOT NULL AUTO_INCREMENT,created DATATIME,PRIMARY KEY(id,created)) ENGINE = INNODB PARTITION BY RANGE (TO_DAYS(created)) (PARTITION foo_1 VALUES LESS THAN (TO_DAYS('2009-01-01')),PARTITION foo_2 VALUES LESS THAN (TO_DAYS('2010-01-01')))
MYSQL通過分區把資料儲存到不同資料檔案裡,同時索引也是分區的,相對未分區的表來說分區後單獨的資料檔案和索引檔案的大小明顯降低,效率明顯提升。一條查詢/寫操作只在相應分區上執行。實際應用分區時,通過DATA DIRECTORY和INDEX DIRECTORY選項把不同分區分散到不同磁碟上進一步提高系統的IO輸送量。使用分區後最好都用EXPLAIN PARTITIONS過一遍以確認分區是否生效。
通常使用Range分區,但在主從結構中主伺服器很少使用SELECT語句在其上使用Range查詢並沒有太大意義,此時使用Hash類型的分區相對更好:PARTITON BY HASH(id) PARTITION 10,當插入資料時會根據ID把資料平均分散到各個分區上,由於檔案小/效率高,更新操作會變得更快。通常按時間欄位分區,不過具體情況還是按需求而定。
分區雖然很好,但目前的實現還有很多限制如:
主鍵或者唯一索引必須包含分區欄位,如PRIMARY KEY (id,created),不過對InnoDB來說,大主鍵效能不好
很多時候使用分區就不要再使用主鍵否則可能影響效能
只能通過INI類型的欄位或者返回INI類型的運算式來分區,通常使用YEAR或TO_DAYS等函數
每個表最多1024個分區,不可能無限制擴充分區,而且過度使用分區會消耗大量系統記憶體
採用分區的表不支援外鍵,相關的約束邏輯必須在代碼裡實現
分區後可能會造成索引失效,需要驗證分區可行性