美文网首页Mysql
索引篇:普通索引和唯一索引的使用

索引篇:普通索引和唯一索引的使用

作者: liugechiji | 来源:发表于2019-07-16 14:40 被阅读0次

    真实场景

    线上某个插入量特别大的表中,从前一天起突然库的内存命中率从99% -> 75%,原因是DBA同学将这个表中的一个普通索引修改成了唯一索引。

    那么,唯一索引和普通索引除了索引唯一的这一特性,查找,更新插入方式有区别吗?

    查找过程

    select id from T where k = 500

    • 对唯一索引来说,查找的时候通过k的索引找到id = 500的那个值之后,停止查找。
    • 对普通索引来说,查找的时候通过k的索引找到id = 500的那个值之后,继续遍历这棵树,知道找到满足条件的那个节点。

    从查找来讲,性能上的差异微乎其微。

    因为InnoDb读写一个数据的时候是按照页作为单位的,一个页的大小为16k,InnoDb会将这个页整个读到内存中去,然后再进行查找和寻根操作,而基本上一次查找大概率都会在一个页中,处于多个页中的情况比较少见,可以忽略不计。

    更新过程

    • changeBuffer简介
      当需要更新一个数据页时,需要先判断这个数据页是不是在内存中,如果不在,就需要将更新的这部分数据先写入到changeBuffer中,这样更新的时候就不用去频繁读取数据页了。下次如果读取从磁盘中读取数据,就会将changeBuffer的数据和数据页中的数据进行merge操作,保证读取数据的一致性。

      将changeBuffer数据应用到数据页,得到更新结果的操作叫做merge,除了访问数据会触发merge之外,还会有线程去定时进行merge操作,在数据库关闭的时候,也会触发merge操作。

      changeBuffer在内存有拷贝,也会被写入到磁盘上,所以当机器断电,宕机的时候,changeBuffer也可以保证数据不会丢失。

    • changeBuffer使用场景
      因为每次更新的时候会直接将数据写入到changeBuffer,减少读磁盘的开销,所以changeBuffer的适用场景也必须要有不读磁盘判断的前提条件。
      如果这个表是写多读多,那么每次读取的时候都会触发一次changeBuffer的merge操作,这反而提升了随机IO,和changeBuffer的维护成本。
      所以得到结论:changeBuffer只可以适用于普通索引,而不可适用于唯一索引,并且这个表是写多读少的场景。

      当前SQL操作语句:insert into T (id, name) VALUES (3, "jasper"),索引为id这个字段。

      • 唯一索引:
        • 如果id = 3数据在内存中,就直接判断3在表中是否存在,不存在就插入,存在就返回。
        • 如果id = 3数据不在内存中,需要将数据页读到内存中,然后判断,执行插入或者返回。
      • 普通索引
        • 如果id = 3插入的位置在内存中,直接更新到内存中。
        • 如果id = 3插入的位置不在内存中, 直接更新到changeBuffer中。
    • changeBuffer和redoLog的区别
      redoLog主要是解决随机写磁盘IO的问题,改成顺序写。
      changeBuffer主要是解决随机读磁盘的IO问题。

    相关文章

      网友评论

        本文标题:索引篇:普通索引和唯一索引的使用

        本文链接:https://www.haomeiwen.com/subject/cnftlctx.html