赞
踩
今天突然奇想,想着如果开启了一个事务,事务操作是修改一条数据记录的索引字段数据,那么这个索引会不会立马更新掉,还是等事务提交后再更新?
我理解是会立马更新的,因为一般来说除了串行化这种隔离级别,其他隔离级别都是支持并行的,某种程度上是可以读取到其他事务的东西,只不过RC这个隔离级别采取了MVCC,但其实还是会更新数据,只不过通过版本链来控制数据透出,所以这里还是会更新索引的,这样就存在下面两个情况
一个SQL执行更新操作,我们简单看下执行流程:
索引更新这么频繁,那么索引树调整也会很频繁,我们从聚簇索引的B+树结构知道,采取这个结构是因为减少磁盘IO次数,那么索引树结构呢?首先还是B+树作为索引结构,但二级索引不一定就是递增的,索引频繁更新会产生大量数据移动的页分裂,在寻找合适位置进行插入时,这样造成的结果就是大量的性能消耗,那么这个问题mysql如何解决呢?
内存缓冲池(buffer pool)以页为单位,缓存最热的数据页(data page)与索引页(index page),一条更新sql的操作就变为:
这样看,没命中缓存也会有一次磁盘IO操作,有没有更好的方式呢
在MySQL5.5之前,叫插入缓冲(insert buffer),只针对insert做了优化;现在对delete和update也有效,叫做写缓冲(change buffer)。它是一种应用在非唯一普通索引页(non-unique secondary index page)不在缓冲池中,对页进行了写操作,并不会立刻将磁盘页加载到缓冲池,而仅仅记录缓冲变更(buffer changes),等未来数据被读取时,再将数据合并(merge)恢复到缓冲池中的技术。写缓冲的目的是降低写操作的磁盘IO,提升数据库性能。步骤大概是:
其中第二步好似欺骗数据库,表明非聚集的索引已经插到叶子节点了,然后再以一定的频率执行插入缓冲和非聚集索引页子节点的合并操作,这时通常能将多个插入合并到一个操作中(因为在一个索引页中),这就大大提高了对非聚集索引执行插入和修改操作的性能,主要还是减少非聚集索引频繁修改带来的性能问题。但是这种方式会带来另一些问题:
这里主要是因为唯一索引会有校验逻辑,校验索引唯一性,肯定要去磁盘读取才能判断,那么这种场景下也就无法优化,而主键索引大多是自增有序,大量的操作影响较小,所以优化的针对就是非唯一普通索引。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。