比較全面的MySQL優化參考

三、MySQL層相關優化

3.一、關於版本選擇

官方版本咱們稱爲ORACLE MySQL,這個沒什麼好說的,相信絕大多數人會選擇它。mysql

我我的強烈建議選擇Percona分支版本,它是一個相對比較成熟的、優秀的MySQL分支版本,在性能提高、可靠性、管理型方面作了很多改善。它和官方ORACLE MySQL版本基本徹底兼容,而且性能大約有20%以上的提高,所以我優先推薦它,我本身也從2008年一直以它爲主。sql

另外一個重要的分支版本是MariaDB,說MariaDB是分支版本其實已經不太合適了,由於它的目標是取代ORACLE MySQL。它主要在原來的MySQL Server層作了大量的源碼級改進,也是一個很是可靠的、優秀的分支版本。但也由此產生了以GTID爲表明的和官方版本沒法兼容的新特性(MySQL 5.7開始,也支持GTID模式在線動態開啓或關閉了),也考慮到絕大多數人仍是會跟着官方版本走,所以沒優先推薦MariaDB。數據庫

3.二、關於最重要的參數選項調整建議

建議調整下面幾個關鍵參數以得到較好的性能(可以使用本站提供的my.cnf生成器生成配置文件模板):併發

一、選擇Percona或MariaDB版本的話,強烈建議啓用thread pool特性,可以使得在高併發的狀況下,性能不會發生大幅降低。此外,還有extra_port功能,很是實用, 關鍵時刻能救命的。還有另一個重要特點是 QUERY_RESPONSE_TIME 功能,也能使咱們對總體的SQL響應時間分佈有直觀感覺;高併發

二、設置default-storage-engine=InnoDB,也就是默認採用InnoDB引擎,強烈建議不要再使用MyISAM引擎了,InnoDB引擎絕對能夠知足99%以上的業務場景;工具

三、調整innodb_buffer_pool_size大小,若是是單實例且絕大多數是InnoDB引擎表的話,可考慮設置爲物理內存的50% ~ 70%左右;性能

四、根據實際須要設置innodb_flush_log_at_trx_commit、sync_binlog的值。若是要求數據不能丟失,那麼兩個都設爲1。若是容許丟失一點數據,則可分別設爲2和10。而若是徹底不用care數據是否丟失的話(例如在slave上,反正大不了重作一次),則可都設爲0。這三種設置值致使數據庫的性能受到影響程度分別是:高、中、低,也就是第一個會另數據庫最慢,最後一個則相反;優化

五、設置innodb_file_per_table = 1,使用獨立表空間,我實在是想不出來用共享表空間有什麼好處了;spa

六、設置innodb_data_file_path = ibdata1:1G:autoextend,千萬不要用默認的10M,不然在有高併發事務時,會受到不小的影響;設計

七、設置innodb_log_file_size=256M,設置innodb_log_files_in_group=2,基本可知足90%以上的場景;

八、設置long_query_time = 1,而在5.5版本以上,已經能夠設置爲小於1了,建議設置爲0.05(50毫秒),記錄那些執行較慢的SQL,用於後續的分析排查;

九、根據業務實際須要,適當調整max_connection(最大鏈接數)、max_connection_error(最大錯誤數,建議設置爲10萬以上,而open_files_limit、innodb_open_files、table_open_cache、table_definition_cache這幾個參數則可設爲約10倍於max_connection的大小;

十、常見的誤區是把tmp_table_size和max_heap_table_size設置的比較大,曾經見過設置爲1G的,這2個選項是每一個鏈接會話都會分配的,所以不要設置過大,不然容易致使OOM發生;其餘的一些鏈接會話級選項例如:sort_buffer_size、join_buffer_size、read_buffer_size、read_rnd_buffer_size等,也須要注意不能設置過大;

十一、因爲已經建議再也不使用MyISAM引擎了,所以能夠把key_buffer_size設置爲32M左右,而且強烈建議關閉query cache功能;

3.三、關於Schema設計規範及SQL使用建議

下面列舉了幾個常見有助於提高MySQL效率的Schema設計規範及SQL使用建議:

一、全部的InnoDB表都設計一個無業務用途的自增列作主鍵,對於絕大多數場景都是如此,真正純只讀用InnoDB表的並很少,真如此的話還不如用TokuDB來得划算;

二、字段長度知足需求前提下,儘量選擇長度小的。此外,字段屬性儘可能都加上NOT NULL約束,可必定程度提升性能;

三、儘量不使用TEXT/BLOB類型,確實須要的話,建議拆分到子表中,不要和主表放在一塊兒,避免SELECT * 的時候讀性能太差。

四、讀取數據時,只選取所須要的列,不要每次都SELECT *,避免產生嚴重的隨機讀問題,尤爲是讀到一些TEXT/BLOB列;

五、對一個VARCHAR(N)列建立索引時,一般取其50%(甚至更小)左右長度建立前綴索引就足以知足80%以上的查詢需求了,不必建立整列的全長度索引;

六、一般狀況下,子查詢的性能比較差,建議改形成JOIN寫法;

七、多表聯接查詢時,關聯字段類型儘可能一致,而且都要有索引;

八、多表鏈接查詢時,把結果集小的表(注意,這裏是指過濾後的結果集,不必定是全表數據量小的)做爲驅動表;

九、多表聯接而且有排序時,排序字段必須是驅動表裏的,不然排序列沒法用到索引;

十、多用複合索引,少用多個獨立索引,尤爲是一些基數(Cardinality)過小(好比說,該列的惟一值總數少於255)的列就不要建立獨立索引了;

十一、相似分頁功能的SQL,建議先用主鍵關聯,而後返回結果集,效率會高不少;

3.三、其餘建議

關於MySQL的管理維護的其餘建議有:

一、一般地,單表物理大小不超過10GB,單錶行數不超過1億條,行平均長度不超過8KB,若是機器性能足夠,這些數據量MySQL是徹底能處理的過來的,不用擔憂性能問題,這麼建議主要是考慮ONLINE DDL的代價較高;

二、不用太擔憂mysqld進程佔用太多內存,只要不發生OOM kill和用到大量的SWAP都還好;

三、在以往,單機上跑多實例的目的是能最大化利用計算資源,若是單實例已經能耗盡大部分計算資源的話,就不必再跑多實例了;

四、按期使用pt-duplicate-key-checker檢查並刪除重複的索引。按期使用pt-index-usage工具檢查並刪除使用頻率很低的索引;

五、按期採集slow query log,用pt-query-digest工具進行分析,可結合Anemometer系統進行slow query管理以便分析slow query並進行後續優化工做;

六、可以使用pt-kill殺掉超長時間的SQL請求,Percona版本中有個選項 innodb_kill_idle_transaction 也可實現該功能;

七、使用pt-online-schema-change來完成大表的ONLINE DDL需求;

八、按期使用pt-table-checksum、pt-table-sync來檢查並修復mysql主從複製的數據差別;

相關文章
相關標籤/搜索