官方版本咱們稱爲ORACLE MySQL,這個沒什麼好說的,相信絕大多數人會選擇它。mysql
我我的強烈建議選擇Percona分支版本,它是一個相對比較成熟的、優秀的MySQL分支版本,在性能提高、可靠性、管理型方面作了很多改善。它和官方ORACLE MySQL版本基本徹底兼容,而且性能大約有20%以上的提高,所以我優先推薦它,我本身也從2008年一直以它爲主。sql
另外一個重要的分支版本是MariaDB,說MariaDB是分支版本其實已經不太合適了,由於它的目標是取代ORACLE MySQL。它主要在原來的MySQL Server層作了大量的源碼級改進,也是一個很是可靠的、優秀的分支版本。但也由此產生了以GTID爲表明的和官方版本沒法兼容的新特性(MySQL 5.7開始,也支持GTID模式在線動態開啓或關閉了),也考慮到絕大多數人仍是會跟着官方版本走,所以沒優先推薦MariaDB。數據庫
建議調整下面幾個關鍵參數以得到較好的性能(可以使用本站提供的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功能;
下面列舉了幾個常見有助於提高MySQL效率的Schema設計規範及SQL使用建議:
一、全部的InnoDB表都設計一個無業務用途的自增列作主鍵,對於絕大多數場景都是如此,真正純只讀用InnoDB表的並很少,真如此的話還不如用TokuDB來得划算;
二、字段長度知足需求前提下,儘量選擇長度小的。此外,字段屬性儘可能都加上NOT NULL約束,可必定程度提升性能;
三、儘量不使用TEXT/BLOB類型,確實須要的話,建議拆分到子表中,不要和主表放在一塊兒,避免SELECT * 的時候讀性能太差。
四、讀取數據時,只選取所須要的列,不要每次都SELECT *,避免產生嚴重的隨機讀問題,尤爲是讀到一些TEXT/BLOB列;
五、對一個VARCHAR(N)列建立索引時,一般取其50%(甚至更小)左右長度建立前綴索引就足以知足80%以上的查詢需求了,不必建立整列的全長度索引;
六、一般狀況下,子查詢的性能比較差,建議改形成JOIN寫法;
七、多表聯接查詢時,關聯字段類型儘可能一致,而且都要有索引;
八、多表鏈接查詢時,把結果集小的表(注意,這裏是指過濾後的結果集,不必定是全表數據量小的)做爲驅動表;
九、多表聯接而且有排序時,排序字段必須是驅動表裏的,不然排序列沒法用到索引;
十、多用複合索引,少用多個獨立索引,尤爲是一些基數(Cardinality)過小(好比說,該列的惟一值總數少於255)的列就不要建立獨立索引了;
十一、相似分頁功能的SQL,建議先用主鍵關聯,而後返回結果集,效率會高不少;
關於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主從複製的數據差別;