MYSQL 性能优化
MYSQL性能优化总结:
1.选择合适的存储引擎:innoDB
除非你的数据表主要做只读或者全文索引,你应该默认选择:innoDB
2.数据表字段设计
a. 通常使用范式化设计,因为范式化通常会似的执行操作更快:
- 第一范式(确保每列保持原子性)
- 第二范式(确保表中的每列都和主键相关)
- 第三范式(确保每列都和主键列直接相关,而不是间接相关)
但我们有时需要混同范式化和反范式化,比如一个更新频率低的字段可以冗余在表中,避免关联查询
b.单表字段不宜过多:建议最多30个以内
c.选择小而简单的合适数据类型,比如字符串类型的,固定长度使用char,非定长度使用varchar,并分配合适且足够的空间;需储存IP字段时选择UNSIGNED INT等
d.尽量将列设置成NOT NULL
e.尽量使用整型做主键,应该尽量避免字符串类型作为标识列,因为它们很消耗空间,并且通常比数字类型慢
f.字段给定默认值,不设为null
g.业务表拆分, 分为业务基本表和业务扩展表
h.不使用触发器
i.尽量避免使用游标,因为游标的效率较差
3.使用索引和索引的优化
一.使用索引为什么快?
- 索引相对于数据本身,数据量小
- 索引是有序的,可以快速确定数据位置
- InnoDB的表示索引组织表,表数据的分布按照主键排序
就好比书的目录,想要找到某一个内容,直接看目录便可找到对应的页
二.索引的存储结构:B+tree和hash
一般选择B+tree
三.索引的类型
按作用分类:
- 主键索引:一般是在建表的时候指定了主键,就会创建主键索引,具有唯一性,不允许空值
- 唯一索引:不允许有重复的值,但允许有空值,速度比普通索引略快
- 普通索引:最基本的索引,没有任何限制
- 全文索引:用作全文搜索匹配,但基本用不上只能索引英文单词,而且操作代价大
按数据存储结构分类:聚簇索引和非聚簇索引
四.索引优化
- 对于经常在where子句使用的列,设置索引,这样会加快查找速度
- 索引不是越多越好,维护索引是需要成本的
- 在连接字段上应该建立索引
- 尽量选择区分度高的列作为索引
- 几个字段经常同时以AND方式出现在Where子句中,可以建立复合索引,否则考虑单字段索引
- 只要列中含有NULL值,最好不要在此列中设置索引
- 尽量使用短索引,如果可以,应该制定一个前缀长度
- 对于有多个列where或者order by子句的,应该建立复合索引
避免索引失效:
- 尽量避免在 where 子句中对字段进行表达式操作和函数操作
- like模糊查询,前缀%会导致索引失效:like ‘%市’
- 避免在Where子句中使用!= 或 <>操作符
- 避免在where子句中对字段进行NULL值判断,否则将导致引擎放弃使用索引而进行全表扫描
- where子句中使用or时,or两边的列都建立了索引,则可以使用索引
- 列的类型需要一致
- 尽量不要使用not in
4.SQL优化
一.sql语句
- 单条查询最后添加LIMIT1 ,停止全表扫描
- 不用mysql内置的函数,因为内置函数不会建立查询缓存
- 将非”索引”数据分离,比如将大篇文章分离存储,不影响其他自动查询
- 不要使用select * from table,用具体的字段列表代替*,不要返回用不到的字段
- 使用join on进行多表查询,不使用子查询,因为子查询会创建临时表,损耗性能
- 避免使用having筛选数据,而是使用where
- order by后面的字段建立索引,利用索引的有序性排序,避免外部排序
- 用exists,not exists和in,not in相互替代
- 多表连接时,尽量小表驱动大表,即小表join大表
- 对于经常使用的查询,可以开启缓存
二.使用Explain分析sql查询语句,选择更好的索引和写出更优化的查询语句
三.开启慢日志,定期查看慢查询日志记录,定位慢查询的sql,进而优化代码
5.架构优化
分库分表(垂直,水平)
分库分表是有成本的
任何分库分表的行为都会提升业务逻辑的复杂度,数据库除了承载数据的存储和访问外,协助业务更好地实现需求和逻辑也是其重要的工作之一。分库分表会带来数据的合并、查询、更新条件的分离,以及事物的分离等多种后果,业务实现的复杂度往往会翻倍或指数级上升。所以在分表分库之前,应先升级硬盘、内存、CPU、网络、版本、读写分离、负载均衡及SQL语句优化。
垂直分表一般是将表中的列按照相关性拆分开
水平分表是按照hash或者时间拆分出来不同的表,每张表的结构是一样的缓存
mysql本身是有缓存机制的,如果开启了查询缓存,我们在查询的时候就会先去缓存查询,但此处的缓存不是指mysql本身的缓存,因为mysql缓存不能减少客户端对mysql的请求访问,因此我们可以在其他地方做缓存,本地或者redis都是很好的选择,合理加上这些缓存,能有效减轻mysql数据库压力。- 读写分离
读写分离即对mysql数据库做集群,以扩展mysql的负载,适用于读操作占主要的场景。主服务器负责写,从服务器负责读(主也可以负责读)。 - 主从复制
主从复制是和上面读写分离配合使用的,用在从库同步主库的数据的时候。
6.配置优化
数据库配置优化
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】- 使用足够大的写入缓存 innodb_log_file_size
操作系统配置优化
网络方面的配置,要修改/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