硬件优化:
1.为提高数据库的IOPS性能,可以使用ssd或者pcie-ssd告诉磁盘设备
2.当数据库系统tps过高或者业务量较高时,一定要配置阵列卡,阵列级别选择REID1+0,而不要选择其他格式
3.在服务器的BIOS层面,设置CPU建议采用最大性能模式,选择performance per watt optimized来充分发挥cpu的最大性能,同时建议关闭C1E和C stats这类节能选项
4.内存方面也可以选择最大性能模式maximun preformance,尽量在BIOS里禁掉NUMA功能,将Node Interleaving设置为Enabled模式
 
mysql应用层面:
1.innodb_buffer_pool_size:当服务器只运行mysqk一个服务的时候,可以设置为总内存的50%-80%。
2.innodb_flush_log_at_trx_commit和sync_binlog:分别是redo log刷新和binlog刷新的参数。如果要求数据不能丢失,建议把这两个参数都设置为1,但如果想要保证强一致性,主从故障切换过程中不丢失数据,可以考虑使用mysql5.7中的增强半哦同步功能
3.innodn_max_dirty_pages_pct:该参数是指脏页占innodb buffer pool的比例。当比例到达所设置的值时,触发刷脏页到磁盘。不要讲该参数设置过大,脏页过多也会影响数据库的tps。建议调整为25%-50%
4.innodb_io_capacity:innodb后台进程最大的I/O性能指标,影响刷新脏页和插入缓冲的数量。默认是200,在高转速磁盘下,可以适当提高该参数的值。ssd磁盘配置下可以调整该值为5000-20000,pcre-ssd可以调整得更高(50000左右)
5.innodb_data_file_path = ibdata1:1G:autoextend:该参数不要使用默认的10MB大小,一般设置为1GB,防止在高并发下,数据库受影响
6.long_query_time:该参数在5.5版本以上已经可以设置为小于1了,建议设置该参数值为0.1~0.5s。记录那些执行比较慢的sql,便于后续优化性能排查
7.binlog_format:建议binlog的记录格式设置为row模式,让数据更加安全可靠,复制过程中不会出现丢数据的情况
8.interactive_timeout,wait_timeout:两个参数分别代表交互等待时间和非交互式等待时间,两个参数设置的值要一致,且必须同时修改,建议调整为300~500s,不要取默认值为8小时
9.max_connections:数据库最大的连接数,不要盲目去调大连接数的数量,应该注意优化业务中的sql语句,让sql快速执行完成,可以释放掉连接。在调高参数的同时,还应该调低interactive_timeout,wait_timeout的值
10.innodb_log_file_size:redo log的值不要太大,如果值太大,当实例恢复时,会消耗大量时间;值太小也会造成日志切换过于频繁
11.gerenal log:全量日志建议关闭,否则该日志会越来越大,造成磁盘空间的紧张,Mysql的性能也会逐渐下降
 
Linux系统层面:
1.I/O调度问题,建议选择deadline或者noop模式。千万不要使用cfq,因为会严重影响数据库性能,操作如下:
cat /sys/block/sda/queue/scheduler
2.文件系统的选择。文件系统推荐采用xfs,其次是选择ext4,基本上可以放弃ext3
3.涉及一个内核参数vm.swappiness,该参数表示使用swap的意向。如果设置该参数值较高,则意味着当内存快耗尽时,倾向于使用swap,而不特意释放内存中的数据。如果设置该值较低,则意味着不倾向使用swap,需要释放内存中的数据,以便用于后续新数据在内存中的续写。该参数可以在1~10范围内取值,不建议设置为0,因为这种行为有可能会导致系统内存溢出(OOM),从而导致Mysql被意外‘kill’掉
cat /proc/sys/vm/swappiness
 
表设计及其他层面:
1.在创建业务表时,库名、表名、字段名必须使用小写字母,采用'_'分割;
2.MySQL数据库中,通过 lower_case_table_names参数来区分表名的大小写,默认为0,代表大小写敏感。如果是1,代码大小写不敏感,以小写存储。为字段选取数据类型时,要秉承着简单、够用的原则。表中的字段和索引数量都不宜过多,要保证SQL语句查询的高效性快速执行完,避免出现堵塞、排队现象。
3.表的存储引擎一定要选择使用InnoDB,之前的章节中已经反复强调过了InnoDB和MyISAM的区别.MySQL5.7基本已经废弃MyISAM,从8.0版本开始,系统表也彻底与 MyISAM告别了。
4.要显式地为表创建一个使用自增列INT或者BIGINT类型作为主键,可以保证写入顺序是自增的,和B+ree叶子节点分裂顺序一致。写入更加高效,TPs性能会更高,存储效率也是最高的。
5.金钱、日期时间、IPv4尽量使用int来存储。用int来存储金钱,让int单位为分,这样就不存在四舍五入了,存储的数值更精确。
6.text和blob这种存大量文字或者存图片的大数据类型,建议不要与业务表放在一起。注:主要业务表切忌出现这样大类型的字段。
7.用 select查询表时只需要获取必要的字段,避免使用 select*。这样可以减少网络带宽消耗,还有可能利用到覆盖索引。
8.很长的字符串列可以考虑创建前缀索引,提高索引利用率
9.所有字段定义中,默认都加上not null约束,避免出现null在对该字段进行select count0统计计数时,可以让统计结果更准确,因为值为null的数据不会被计算进去
10.表的字符集默认使用UTF8,必要时可申请使用UTF8mb4字符集。因为它的通用性比GBK、Latin1都要好。UTF8字符集存储汉字占用3个字节,如果遇到表情存储的需求,就可以使用UTF8mb4
11.建议模糊查询 select ... like '%**%'的语句不要出现在数据库中,可以使用搜索引擎代替。
12.索引字段上面不要使用函数,否则使用不到索引,也不要创建函数索引
13.join列类型要保持一致,其中包括长度、字符集都要一致。
14.当在执行计划中的exatra项看到 Using filesort,或者看到 Using temporary时,也要优先考虑创建排序索引和分组索引
15.limit语句上的优化,建议使用主键来进行范围检索,缩小结果集大小,使查询更高效
16.通常情况下,可以使用mysql自带的工具mysqldumpslow或者最常使用的第三方工具软件pt-query-digest来捕获线上影响业务的慢查询语句
17.还可以使用mysql提供的可以用来分析当前会话中语句执行资源消耗情况的命令show profile。
开启profile
set profiling=1;
show profiles;
show profile for query 1;查看资源消耗的情况
show profile block io,cpu for query 1;查看sql语句消耗cpu和磁盘I/O情况
 
18.在mysql数据库中,可以通过使用show global status命令查看数据库的运行状态,通过得出的数值优化mysql运行效率