MYSQL 数据库优化

本文整理收录《阿里JAVA开发手册》 《58到家数据库30条军规》 以及网上各文章 关于MYSQL数据库优化通用的部分

纵向优化:字段设计、表库设计、搜索引擎、建立索引、SQL语句优化(效果最不明显)
横向优化:负载均衡(Nginx 轮询、IPhash、权重)、读写分离、主从复制

字段优化:
1、非负数使用unsigned
2、255以内用tinyint 65535用smallint 42亿用int 更大用bigint
3、用0 1 表示是与否、男和女等等,而不要用枚举变量
4、一定设置非null ,加默认值。null 在数据库里是特殊对象,影响性能,尽量避免
5、金额用整数或者decimal来存储,而不要用float、double 会有精度损失
6、使用冗余字段来 建立索引
7、图片、视频的存储使用文件系统,而数据库里存放其URI

表库优化:
水平分表,比如博客数据库的博文字段(TEXT)过大,单独分一张表来存储博文
垂直分表,MYSQL 记录过多会明显性能下降,把多条记录分多张表存储
在高并发的业务场景下禁止使用外键和级联更新,一切外键的功能在应用层解决。
级联更新是强阻塞,存在数据更新风暴的风险,外键会影响数据库的插入速度,并且使表和表之间耦合,不适合发展分布式 高并发集群。
禁止使用存储过程,难以调试和拓展,没有移植性
ps:以上几条仅针对高并发业务场景,单机低并发随意

索引建立:
1、在where、orderby 、join 等用到的字段上建立索引
2、建立索引会影响插入性能,因此频繁更新的表不要使用索引
3、可以考虑冗余字段来 用于建立索引。
4、多表关联查询必须保证字段有索引。

索引类型:
1、普通索引
2、主键索引
3、唯一索引
4、组合索引
5、全文索引
索引数据结构:Btree(默认)、Rtree(少用),fulltext(针对模糊查找,仅MyISAM支持),Hash(仅对‘in’ ‘=’高效)

搜索引擎:
读多写少用MyISAM ,比如博客、新闻(MyISAM仅仅在读取性能上稍稍占优)
读多写多用InnoDB。
两者区别:
1、InnoDB 行级锁,MyISAM 表级锁,InnoDB并发性能远远高于MyISAM。
2、InnoDB 支持事务、外键,保证数据一致性,完整性。MyISAM不支持事务、外键。
3、InnoDB 读写阻塞和事务隔离级别相关,MyISAM读写阻塞,读和写不能同时进行。
4、InnoDB支持聚簇索引。数据和索引放在同一表空间。MyISAM不支持。
5、InnoDB支持MVCC高并发,MyISAM不支持。
MVCC多版本并发控制:每条记录都有隐藏默认字段记录了创建和删除的事务编号(时间),根据时间来显示客户在查询时候看到的记录。
现在数据库引擎默认都是使用InnoDB。
其他:
禁止左模糊和全模糊,会导致全表扫描。
分页查询: select 字段 from table limit(pageNo -1) * size, size
设置查询缓存
使用explain SQL 查询是否 全表搜索、是否使用了索引 来进行优化。
主从复制、读写分离。

B树:
B树是多路自平衡树,可以看做是二叉搜索树的升级版。在平均查询效率上两者差不多,但BST二叉搜索树极端情况会存在不平衡的问题,也就是最差情况下,二叉搜索树会退化为一个单向链表(复杂度为O(n))。为了防止这种情况,B树的定义决定了它会自平衡,使得所有节点子树的深度差距不超过1,最差情况也能达到O(logn)的查找效率。
B树叶子节点的元素个数称为‘阶’,其大小取决于内存的大小(磁盘页)。每次访问一个节点就是一次磁盘IO的过程,磁盘IO的速度和CPU的速度相差几个数量级,因此内存大小允许情况下,阶数越大,树的高度会越小,磁盘IO次数会越少,查找会越快速。(空间换时间)
B-树和B+树的区别: B-树中,每个结点存储数据和索引。而B+树中,只有最下层的叶子节点存放数据。因此B+树的节点能存放更多的索引。B+树中用叶子节点存放数据,并且数据用链表相连,所以B+树在区间查找和遍历方面会优于B-树。B-也有优点,由于每个节点都存放数据,因此最优查找效率又是高于B+树。

事务:
ACID特性 :
1、原子性,要么都做,要么都不做,如果中间出错则回滚。
2、一致性,事务开始和结束,数据库的完整性不被破坏。(主要指的是主键约束、外键约束等等)
3、隔离性,多个事务对同一条数据的操作 是串行的,而不是并行的。
4、持久性,事务完成后便被保存。

脏读:A执行了修改,但是B在A提交前就读取了数据,最终A却回滚了。也就是读取了想修改却最终没修改的数据
不可重复读:A 在一次事务中多次读取某一数据,但B在过程中更新了那一数据,导致A的多次读取数据不一致。
幻读:幻读和不可重复读类似,但幻读重在记录的新增和删除上,而不可重复读的表现是一条记录前后不一致。比如A 把所有学生的成绩设置为0,过程中B插入了一条新学生数据,那么这一条就没有被更新到,就是幻读。
事务隔离级别:1、串行化Serializable 最安全,也最低效。不会出现脏读、幻读、不可重复读。
2、可重复读 repeatable-read ,可能出现幻读
3、提交读 read-commited 可能出现幻读、不可重复读
4、未提交读 read-uncommitted 可能出现幻读、不可重复读、脏读。

你可能感兴趣的:(后端,Mysql,后端)