当前位置: 首页 > wzjs >正文

免费 网站点击1688阿里巴巴官网首页

免费 网站点击,1688阿里巴巴官网首页,vue seo优化,浦口区网站建设唯一索引:字段值不能重复。普通索引:字段值可以重复。假设数据如下图,且字段k上的值都不重复:接下来,从两种索引对查询语句和更新语句的性能影响来分析。查询过程假设查询语句为select id from T where k5。那么首先会…

唯一索引:字段值不能重复。

普通索引:字段值可以重复。

假设数据如下图,且字段k上的值都不重复:

接下来,从两种索引对查询语句和更新语句的性能影响来分析。

查询过程

假设查询语句为select id from T where k=5。那么首先会在字段k的索引树上找到k=5所在的数据页,然后在数据页内二分查找记录。对于普通索引和唯一索引,区别为:

  • 普通索引,查找到满足条件的第一个记录后,会继续查找,直到找到第一个不满足k=5的记录。

  • 唯一索引,找到第一个满足条件的记录后,就停止查找。

这个区别带来的性能差距其实是不大的。由于InnoDB的数据按数据页为单位进行读写,当找到k=5的那条记录时,它所在的数据页就都在内存里了,因此普通索引多进行的一次查找并没有多大开销。尽管有可能k=5刚好是数据页的最后一条记录,查找下一条记录需要新读取一页,但这种可能出现的概率很低,均摊到所有可能后成本可以忽略不计。

更新过程

在分析更新过程之前,先介绍change buffer。

当需要更新一个数据页,如果数据页在内存中,就直接更新;如果数据页在磁盘中,在不影响数据一致性的前提下,InnoDB会将这些更新操作缓存在change buffer中。当下次查询需要访问该数据页,会将该数据页读入内存,执行change buffer中与该页有关的操作来保证数据逻辑的正确性。

change buffer在内存中,也会被持久化到磁盘上。

将change buffer中的操作应用到原数据页,得到最新结果的过程称为merge。除了访问这个数据页会触发merge,系统有后台线程会定期merge。在数据库正常关闭的过程中,也会执行merge操作。

可以看出,如果能将更新操作先记录在change buffer,减少读磁盘的次数,语句执行速度将会加快。而且,数据读入内存需要占用buffer pool,使用change buffer还能避免占用内存,提高内存利用率。

并不是所有条件下都可以使用change buffer。对于唯一索引,所有更新操作都必须判断该操作是否违反唯一性约束,比如要插入(4,400),就需要先判断表中是否已经有k=4的记录,因此每次更新都需要将数据页读入内存。而如果本身有读入内存的操作,那么直接更新内存即可,不需要再使用change buffer。而对普通索引,change buffer是可以使用的。

change buffer用的是buffer pool里的内存,不能无限增大。其大小可以通过innodb_change_buffer_max_size来动态设置,参数值表示占用buffer pool的百分比。

那么来看看,如果想要插入一条k=4的新纪录,InnoDB的处理流程:

  • 对于唯一索引,找到3和5之间的位置,判断到没有冲突,插入值;

  • 对于普通索引,找到3和5之间的位置,插入值。

看起来两者只相差一个判断,但若该记录要更新的目标页不在内存中,再对两者进行比较:

  • 对于唯一索引,需要将数据页读入内存,判断到没有冲突,插入值;

  • 对于普通索引,将更新记录在change buffer即可。

可以看到,这种情况下相差了一次随机磁盘IO,性能相差较大。

change buffer的使用场景

尽管change buffer能用于普通索引的场景,但并不是在所有情况下它都能起到加速作用。

这是由于merge是真正进行数据更新的时刻,而change buffer的主要目的就是将记录的变更动作缓存下来,所以在一个数据页merge前,change buffer记录的变更越多,收益越大。

对于写多读少的业务场景,页面写完后马上被访问的概率较小,意味着change buffer马上merge的概率较小,此时使用效果较好,场景业务模型如账单类、日志类系统。

而对于一个写入之后马上做查询的场景,merge的频率较高,这样随机访问IO的次数并不会减少,反而增加了change buffer的维护代价。因此,对于这种业务模式来说,change buffer反而起到了副作用。

索引选择和实践

回到之前的问题:如何选择普通索引和唯一索引。

经过上面的分析可以看到,两者在查询过程的能力几乎无差别,主要区别在更新过程。因此,建议尽量选择普通索引。如果是写入后马上查询的场景,建议关闭change buffer

普通索引 + change buffer,对于数据量大的表的更新优化是比较明显的。特别地,在使用机械硬盘时,change buffer机制收益非常显著,因此使用机械硬盘时考虑加大change buffer。

change buffer和redo log

理解了change buffer的原理,可能会发现这和redo log有一些相似。

让我们回顾redo log的WAL机制:MySQL的更新用到了WAL(Write-Ahead Logging)技术,关键点就是先写日志,再写磁盘。具体来说,当有一条记录需要更新时,InnoDB引擎先将记录写到redo log并更新内存,这时更新就可以算完成了。之后,InnoDB会在适当的时候将这个操作记录更新到磁盘里。

接下来,使用一个例子来区分这两个概念。假设要在表上执行下面这个插入语句:

insert into t(id,k) values(id1,k1),(id2,k2);

假设在k索引树找到位置后,k1所在的数据页在内存中,而k2所在的数据页不在内存中。下图是带change buffer的更新状态图:

分析这条更新语句:

  • 发现Page 1在内存中,直接更新内存;

  • 发现Page 2没有在内存中,就在内存的change buffer区域,记录“我要往Page 2插入一行”这个信息;

  • 将上述两个动作记入redo log。

做完上述动作,事务就完成了。可以发现,对于该次更新,只是写了两次内存+一次磁盘。图中的虚线箭头是后台操作,不会影响更新的响应时间。

那么此次更新之后的查询请求,会怎么处理呢?

比如要执行select * from t where k in (k1,k2),其读请求的流程图如下:

分析这条查询语句:

  • 读Page 1时,直接从内存返回。

  • 读Page 2时,需要先将Page 2从磁盘读入内存,然后应用change buffer,生成一个正确版本并返回结果。

因此,如果简单对比change buffer和redo log在提升更新性能上的收益的话:

  • redo log主要节省了随机写磁盘的IO消耗,将随机写转为了顺序写;

  • change buffer节省了随机读磁盘的IO消耗。

最后,做一个思考:如果某次写入使用了change buffer,如果之后主机异常重启,是否会丢失change buffer和数据?

答案是不会,因为在写完change buffer后,会把该动作也记录到redo log后,之后崩溃恢复也可以通过redo log找回。

http://www.dtcms.com/wzjs/577238.html

相关文章:

  • 织梦cms如何搭建网站建筑招标信息网官网
  • 网站设计专业公司价格信息分类平台
  • 网站核验单下载wordpress 图片多
  • 义乌网站建设和制作浙江平板网站建设
  • 实搜石家庄网站建设小程序做小型企业网站多少钱
  • 网站建设公司海外赣州公司做网站
  • 绵阳科技网站建设磐安县建设局网站
  • 建网站相关知识购买域名是什么意思
  • 乐都区公司网站建设最近免费高清版电影在线观看
  • 延安网站优化驻马店做网站优化
  • 怎么做网站教程 用的工具网站设计与运营
  • 专业网站建设公司哪家专业网络公司排名中国科技企业排行榜
  • 推广自己的网站需要怎么做wordpress追加表
  • 备案期间怎么关闭网站aspcms 网站地图
  • 家乡网站设计模板上海招标网
  • 网站logoico怎么做做服装搭配图的网站
  • 网站制作网站开发ple id充值家政网站模板
  • 新乡seo网站推广工具做网站主要用哪种语言
  • 做网站如何下载别人网站图片沈阳网站制作全过程
  • c 网站开发简单实例长春网站开发培训价格
  • 大朗网站建设英文seo 文章发布类网站
  • 烟台优化网站公司天津seo排名
  • 网站建设尢金手指专业ui交互设计师主要做什么的
  • 做旅游网站的玉林城乡住房建设厅网站
  • 企业网站建设最需要的是什么wordpress付费主题
  • 常做网站首页的文件名wordpress 短代码嵌套
  • 苏州网站快速排名优化网站制作复杂吗
  • 在线免费网站排名优化asp网站的安全性
  • 10个零网站建设中文手机网站设计案例
  • 洞口网站开发公司推荐聊城网站改版