官方版本咱们称为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主从复制的数据差别;