为啥添加索引会使表数据新增变慢?
- 需要多维护一棵tree 的索引文件,增加了IO次数。
- 非聚族索引的新增的索引数据不是顺序的,增加了随机IO,但是有一些也是索引也是顺序的的,例如:下单时间等。
- 在innodb 存储引擎中,在innodb 1.0.x 中是使用缓冲池中insert buffer 对非唯一性辅助索引的新增维护进行了优化,在缓存中会对多个新增索引的操作进行合并操作,新增的时候会判断索引位置的page 页是否在缓存池中,如果在直接添加,如果不在就先往innsert buffer中添加索引信息,让MySQL服务器以为已经维护好了,在异步进行innsert buffer的合并写,减少了对IO磁盘的操作,如果服务器挂了,那么恢复服务器的时间就可能需要更久了。
为啥建议使用mysql 的主键是递增的(不需要顺序递增)
总所皆知,MySQL的有一列聚族索引(数据跟着索引一起,没有分开),聚族索引可以根据ID快速的查找数据,不需要进行额外的地址转化。
聚族索引是顺序的话,就可以避免的插入的随机IO了。
聚族索引是顺序的话,就可以减少页分裂等影响IO性能的问题,如果不是顺序的,新增的数据因为B tree的数据结构,需要找到合适的位置把新增的数据添加进去,这样就会造成,页分裂和页碎片问题。
binLog 日志
binlog 日志的3中格式
- STATMENT:基于语句的进行复制,占用空间小,像UUID(),NOW(),CONNECTION_ID()函数时,复制是有问题的
- ROW: 基于行进行辅助,占用空间较大,
- MIXED: 混合模式,一般情况下使用STAEMNT 格式,只有出现CONECTION_ID(),UUID(),NOW() 等不确定函数时才会使用ROW格式
开启binlog日志
默认值关闭,开始会影响服务器的一小部分性能,如果越会影响1% 的服务器性能。
设置 sync_binlog=1 的话,每次事务提交之前就需要保存binlog日志,这样就存在保存了binlog日志没有提交事务的情况,会导致数据错乱。
这个时候需要保证bin_log 和 redo log 的数据的一致性,可以设置innodb_support_xa (mysql 8.0 该参数已经被移除了)参数来控制binlog和redo log的操作;
innodb_support_xa =1 可以获得更大的程度的安全性。
binlog日志是属于mysql服务层级别的,跟存储引擎的无关。记录的是逻辑数据。
redo log
默认一个事务日志组,2个日志问题,循环添加日志,每个文件默认大小为:48MB,这个文件设置的太大,会导致mysql宕机后,恢复事务日志的时间变长,设置的太小会导致频繁切换文件,影响IO效率。
redo log 只有innodb 存储引擎才有,用来支持事务的ACID特性的,redo log有个非常重要的参数:innodb_flush_log_at_trx_commit,默认值为1
innodb_flush_log_at_trx_commit
0:表示mainThread 每秒钟提交的事务进行持久化刷盘
1:表示每次事务提交都需要把redo log 记录到磁盘,调用fync(),并持久化,保证了只有提交了事务,就不会丢失
2:表示每次事务提交都同步redo log 日志,但不会进行刷盘,需要依赖每秒刷盘的mainThread和操作系统的持久化机制,这种机制也会导致事务丢失,如果mysql服务器宕机了,但是mysql节点的服务器还在,这样操作系统可以继续刷盘。