普通索引和唯一索引的区别
查询区别:
- 在innodb索引组织结构下,使用普通索引查询和使用唯一索引查询差别不大,普通索引和唯一索引都是使用B+Tree,不同的是普通索引使用等值查找法,直到查到不符合的数据为止,而唯一索引因为定义了唯一性,在查找到第一个满足条件的数据后就停止。
更新区别:
当更新数据在内存中时:
- 普通索引:在change buffer中记录更新
- 唯一索引:直接在内存中更新数据
当更新数据不再内存时:
* 普通索引:
将更新记录进change buffer,结束;change buffer会定期merge到原数据页,在访问该数据页时也会发生merge,在数据库关闭时也会触发merge。
-
change buffer,实际上它是可以持久化的数据。也就是说,change buffer 在内存中有拷贝,也会被写入到磁盘上。将 change buffer 中的操作应用到原数据页,得到最新结果的过程称为 merge。除了访问这个数据页会触发 merge 外,系统有后台线程会定期 merge。在数据库正常关闭(shutdown)的过程中,也会执行 merge 操作。显然,如果能够将更新操作先记录在 change buffer,减少读磁盘,语句的执行速度会得到明显的提升。而且,数据读入内存是需要占用 buffer pool 的,所以这种方式还能够避免占用内存,提高内存利用率。
-
change buffer 和 redo log 区别:
- change buffer和redo log颗粒度不一样,因为change buffer只是针对如果更改的数据所在页不在内存中才暂时储存在change buffer中。而redo log会记录一个事务内进行数据更改的所有操作,即使修改的数据已经在内存中了,那也会记录下来
-
change buffer 使用的是buffer pool 中的内存,因此change buffer 不能无限增大。change buffer 大小可以通过参数 innodb_change_buffer_max_size 来动态设置。这个参数设置为50,表示change buffer 的大小可以最多占用buffer pool 内存的50%
-
change buffer 的是使用场景:
-
适用于多写少读的情况,如果在写入数据后紧跟查询操作,那么这种情况并不适合change buffer 因为这个操作虽然是将数据先写入change buffer 但随后紧跟查询,会立即触发merge
-
change buffer 目的:
-
将记录的动作缓存下来,所以在数据页merge之前记录的变更越多收益越大
唯一索引:
- 将数据以页的方式读入内存,在内存中修改数据(因为唯一索引在修改数据时需要知道内存中是否存在当条数据,会将数据以页的方式读入内存,此时数据已经在内存,显然此时直接修改内存数据更加划算,所以唯一索引使用不到Change buffer,并且说明唯一索引在写方面不如普通索引)
- 在InnoDB引擎中每个数据页大小默认16kB
总结:
- 读取方面:普通索引和唯一索引性能差距不大,但是唯一索引略胜一筹
- 写数据:普通索引因为使用到了Change Buffer 性能比唯一索引高
- Channge Buffer使用场景:
-
适用于多写少读的场景,如果所有写完以后马上读取本条Change BUffer反而会起到副作用,此时应该关闭change buffer
innodb_change_buffer_max_size设置为0
-
4.redo log 减少随机写磁盘的io消耗,change buffer 减少随机读磁盘的io消耗