總述
在我們使用mysql的過程中,隨着我們對mysql的深入瞭解和使用,mysql性能優化是無法避免的話題。以下總結是基於我自己的mysql使用經驗和網上比較優秀的文章。
mysql性能優化劃分
1.sql優化
- 避免索引失效
不要在where子句中使用or
like模糊查詢,前綴%會導致索引失效:like “%市”
避免在where子句中使用!=或<>操作符
避免在where子句中對字段進行null值判斷
避免在 where 子句中對字段進行表達式操作或者函數式操作,如:select id from scoreTable where score/2>40 - 定期查看慢日誌記錄,優化代碼
開啓慢日誌會對mysql性能產生影響,但是有助於我們查看隱藏的問題,作爲開發人員,應該定期查看慢日誌記錄,定位慢查詢的sql,進而優化代碼。 - 其他
任何地方都不要使用 select * from t ,用具體的字段列表代替 * ,不要返回用不到的任何字段。
2.表設計優化
- 字段都給定默認值,不設爲null
- 業務表拆分 分爲業務基本表和業務擴展表
- 不使用觸發器
- 儘可能的使用 varchar/nvarchar 代替 char/nchar ,因爲首先變長字段存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的字段內搜索效率顯然要高些。
3.架構優化
- 分庫分表(垂直,水平)
分庫分表是有成本的
任何分庫分表的行爲都會提升業務邏輯的複雜度,數據庫除了承載數據的存儲和訪問外,協助業務更好地實現需求和邏輯也是其重要的工作之一。分庫分表會帶來數據的合併、查詢、更新條件的分離,以及事物的分離等多種後果,業務實現的複雜度往往會翻倍或指數級上升。所以在分表分庫之前,應先升級硬盤、內存、CPU、網絡、版本、讀寫分離、負載均衡及SQL語句優化。
垂直分表一般是將表中的列按照相關性拆分開
水平分表是按照hash或者時間拆分出來不同的表,每張表的結構是一樣的 - 緩存
mysql本身是有緩存機制的,如果開啓了查詢緩存,我們在查詢的時候就會先去緩存查詢,但此處的緩存不是指mysql本身的緩存,因爲mysql緩存不能減少客戶端對mysql的請求訪問,因此我們可以在其他地方做緩存,本地或者redis都是很好的選擇,合理加上這些緩存,能有效減輕mysql數據庫壓力。 - 讀寫分離
讀寫分離即對mysql數據庫做集羣,以擴展mysql的負載,適用於讀操作佔主要的場景。主服務器負責寫,從服務器負責讀(主也可以負責讀)。 - 主從複製
主從複製是和上面讀寫分離配合使用的,用在從庫同步主庫的數據的時候。
4.配置優化
- 數據庫配置優化
Linux系統中MySQl配置文件一般位於/etc/my.cnf
常用配置參數:
innodb_buffer_pool_size【用於配置Innodb的緩衝池,如果數據庫中只有Innodb表,則推薦配置量爲總內存的75%】
innodb_buffer_pool_instances【MySQL5.5中新增參數,可以控制緩衝池的個數,默認情況下只有一個緩衝池】
innodb_flush_log_at_trx_commit【關鍵參數,對innodb的IO影響很大。默認值爲1,可以取0,1,2三個值,0最快,1最安全,2折中。一般建議設爲2,但如果數據安全性要求比較高則使用默認值1】 - 操作系統配置優化
網絡方面的配置,要修改/etc/sysctl.conf文件
增加tcp支持的隊列數
net.ipv4.tcp_max_syn_backlog = 65535
減少斷開連接時 ,資源回收
net.ipv4.tcp_max_tw_buckets = 8000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 10