页的概念
在计算机里,无论是内存还是磁盘,操作系统都是按页的大小进行读取的(页大小通常为 4 kb),磁盘每次读取都会预读,会提前将连续的数据读入内存中,这样就避免了多次 IO,这就是计算机中有名的局部性原理,即我用到一块数据,很大可能这块数据附近的数据也会被用到,干脆一起加载,省得多次 IO 拖慢速度, 这个连续数据有多大呢,必须是操作系统页大小的整数倍。
所以MySQL 的页,默认值为 16 KB,也就是说对于 B+ 树的节点,最好设置成页的大小(16 KB),这样一个 B+ 树上的节点就只会有一次 IO 读。
那有人就会问了,这个页大小是不是越大越好呢,设置大一点,节点可容纳的数据就越多,树高越小,IO 不就越小了吗,这里要注意,页大小并不是越大越好,InnoDB 是通过内存中的缓存池(pool buffer)来管理从磁盘中读取的页数据的。页太大的话,很快就把这个缓存池撑满了,可能会造成页在内存与磁盘间频繁换入换出,影响性能。
为啥推荐自增 id 作为主键
-
第一个原因就是自增主键一般都会设置为int,占用4个字节,所有可以这样说,InnoDB的B+树最多为4叉。
-
第二个原因就是,假如以其他属性为主键,可能由于这个数的随机性造成大量页的分裂和合并导致性能急剧下降,但是如果是自增ID,他这个值一定是比之前数都大的,所以在插入时要么放到元素个数还没满的已存在节点,要么放入新建的节点中,就不存在上述问题了。
MySQL调优
引擎选择
InnoDB 和 MyISAM区别:
1、InnoDB支持主外键、事务;
2、InnoDB是行锁,操作时候只锁一行数据,适合高并发;MyISAM是表索;
3、InnoDB不仅缓存索引,还缓存真实数据;MyISAM只缓存索引;
4、InnoDB需要表空间大;
5、InnoDB关注事务,MyISAM关注性能(查)
使用选择:
MYISAM小巧玲珑, 节约空间, 速度快
INNODB安全性好, 有事务的处理和多表多用户的操作
行锁升级表锁
表的设计
按照三范式规则
索引优化
- 索引数据结构
不使用hash表是因为不方便进行范围查找
不使用二叉树的原因是树的深度太高了
不使用b树的原因是有更好的b+树
首先要知道在b树和b+树中, 数据都是放在叶子上的, 而且已过父节点可以有多个子节点
b树虽然已过节点可以有多个分支, 树的深度降低不少, 但是在进行范围查找的时候还是不如b+树
因为b+树在叶子节点上是连续的
在适当情况添加索引:
索引不是越多越好, 他只会提高查找效率, 删除修改, 增加的效率只会降低
不要给经常变更的数据加索引
小数据量有没有必要加索引
索引一般用在查询上, 在增加删除修改方便索引的效率是降低的, 所以用在查多改少的情况
如果某一个字段选择性很少, 比如性别, 类型, 他们的取值范围很小, 也不适合添加索引
sql语句优化
- 减少selec *的使用
- 不使用NOT IN和<>操作
- 在SQL文里面对某个字段经过运算后再与一个常量比较:那么这将会对运行性能产生很大的影响
- 一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 和like “%aaa” 不会使用索引而like “aaa%”可以使用索引。
- mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
设计连接池实现优化
我们普通执行一个数据库操作, 获得数据库连接->执行->释放
如果多次进行连接释放这是很浪费资源的
池化技术: 准备一些预先的资源,需要执行了直接用预先准备好的就行
可以设置最小连接数啊最大连接数啊等待超时啥的
如果想自定义一个连接池的话直接实现DAtaSource接口即可, 使用了这些数据库连接池之后,我们在项目中开发就不需要编写连接数据库的代码了
或者使用市面上优秀数据源DBCP和C3P0和德鲁伊, 但是他们的本质还是实现了DataSource接口