zoukankan      html  css  js  c++  java
  • 普通索引和唯一索引,应该如何选择

    /*
    
     1.在innodb中每个数据页的大小默认是16KB
    2.对于普通索引来说,在查询时查到满足条件的第一天记录的时候需要查找下一个记录,直到碰到第一个不满足 k=5 条件              的记录
    3.对于唯一索引来说因为定义了唯一性,所以查到第一个满足条件的记录后就会停止查询
    普通索引和唯一索引的性能差异微乎其微
    change buffer 
    在内存中有缓存这mysql数据页,如果在更新的时候,把磁盘内容改了,但是内存数据还没改回出现数据不一致,这时候就需要 change buffer,innodb会将这些更新操作缓存在change buffer,下次如果需要访问这个数据页,将这个数据页读入内存,然后执行change buffer中有关这个数据页的操作,最终还是会将数据写入磁盘。
    
    change buffer 这个操作应用到原数据页,得到新结果的过程叫做merge
    
    那么什么情况下可以使用change buffer?
    唯一索引;对于唯一索引来说,所有的更新操作多会先判断这个操作是否违反了唯一约束,比如要插入一条(4,400)需要先判断一下表中是否存在k=4这条记录,并且是必须要将数据页读入内存才能判断。如果都已经读入内存了,,那直接更新内存会更快,就没必要使用change buffer,
    因此唯一索引的更新就不能使用change buffer了,实际上也只有普通索引可以使用
    change buffer 用的是 buffer pool 里的内存,因此不能无限增大。change buffer 的大小,可以通过参数 innodb_change_buffer_max_size 来动态设置。这个参数设置为 50 的时候,表示 change buffer 的大小最多只能占用 buffer pool 的 50%。
    
    第一种情况:这个更新的目标记录在内存中,在innodb中一条更新操作是如何执行的,一条新数据(4,500)
    唯一:找到3和5的这个位置判断有没有冲突,如果没有插入数据。
    普通:找到3和5的位置,插入数据
    他们的区别是多了一个判断,这对于cpu来说差异很微小
    
    第二种情况:这个记录要更新的目标数据页不在内存中
    唯一:先将目标数据页读入内存中,判断目标是否冲突,再来写入
    普通:将更新操作记录在change buffer中,执行结束
    change buffer减少了对磁盘的随机访问,所以对更新的性能提升还是明显的
    
    
    change buffer的应用场景
    
    通过上面我们知道change buffer对更新操作的加速过程,且只限于普通索引,而不适用于唯一索引。
    
    问题:普通索引的所有应用场景都适用于change buffer吗?
    change buffer是将我们对一个数据页的更新操作记录下来,所以在一个数据页做merge前,change buffer记录的变更越多(也就是更新次数越多),收益越大
    因此对于写多读少的业务来说,页面在写完马上被访问的概率小,此时使用change buffer的效果最好
    这种常见业务有,账单,日志等
    
    反之,如果一个业务写完马上就做查询,那么即使满足条件,将更新先记录在change buffer,但马上进行访问,会立即触发merge过程,这样随机访问IO次数并不会减少,还会增加change buffer 的维护代价,所以这种业务使用change buffer反而会起反作用。
    
    
    
    所以普通索引和唯一索引到底该如何选择
    我们知道在查询方面他们是没什么差别,主要是考虑在更新上面的性能。所以尽量选择普通索引
    
    如果在更新后马上会进行查询操作,应该关闭change buffer ,而在其他情况下change buffer都能有明显的性能提升
    如何开启关闭change buffer呢?
    可以通过参数innodb_change_buffering来控制是否启用change buffer。
    --all:      默认值。开启buffer inserts、delete-marking operations、purges
    --none: 不开启change buffer
    --inserts:  只是开启buffer insert操作
    --deletes:  只是开delete-marking操作
    --changes:  开启buffer insert操作和delete-marking操作
    --purges:   对只是在后台执行的物理删除操作开启buffer功能
    
    
    为什么change buffer能够支持数据持久化呢?
    change buffer 会将操作记录在redo log如果服务器意外关闭,在redo log这个日志文件中还有记录
    
    redo log 这个主要是用来节省随机写入IO磁盘的消耗(转为顺序写)
    而change buffer这个是来节省随机读IO磁盘的消耗
    
    
    */
  • 相关阅读:
    12.python笔记之mysqldb模块
    13.python笔记之pyyaml模块
    11.python之线程,协程,进程,
    2.saltstack笔记之目标,模块,返回写入数据库
    6.django笔记之orm
    5.django笔记之form保存表单信息,动态select
    4.django笔记之admin
    docker批量删除none镜像
    docker 给none镜像打镜像
    jenkins卡在等待界面解决方法
  • 原文地址:https://www.cnblogs.com/LF-place/p/11537514.html
Copyright © 2011-2022 走看看