09 普通索引和唯一索引
对于查询
普通索引找到之后 还会继续向下遍历到不等于条件
唯一索引找到直接退出。
由于是按页读取的,所以遍历代价很小。
对于更新
change buffer
如果更新时,数据也在内存中就直接更新,如果不在,则在不影响数据一致性的前提下,将更新操作缓存在change buffer,这样就不需要从磁盘读取。在下次查询这个数据页的时候,然后再执行change buffer的操作。
change buffer会被写入到磁盘。
执行change buffer得到最新结果的过程称为merge,访问这个数据页会meger,也有后台线程定期merge,数据库正常关闭也会merge。
- 唯一索引,需要将数据页读入内存中,来判断有没有唯一冲突,所以用不到channel buffer。还需要读磁盘。
- 普通索引,直接将更新记录写在channge buffer中,语句就结束了。
change buffer记录的越多 收益就越大,查询操作会访问这个数据页,就会触发merge。反而副作用了。
所以对写多读少的业务,收益最大。
和redo log
redo log 主要节省的是随机写磁盘的 IO 消耗(转成顺序写),而 change buffer 主要节省的则是随机读磁盘的 IO 消耗。
10 索引选择
analyze table t 重新统计索引信息
force index 强制选择一个索引
11字符串索引优化
前缀索引
长度越小占用空间越小
结合业务定义好长度,即节省空间,又不用额外增加太多查询成本。
无法利用覆盖索引
倒序存储
额外hash字段
12 刷脏页(flush)
当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁
利用WAL技术,数据库将随机写转换成了顺序写,大大提高了性能。但是,带来了内存脏页的问题。
flush会占用资源。
13 表删除
删除数据 插入数据(随机插入)都会造成空洞
alter table A engine=InnoDB 重建表 收缩数据空洞(90%满 )
14 count
count(字段),则表示返回满足条件的数据行里面,参数“字段”不为 NULL 的总个数
count(*) 是例外,并不会把全部字段取出来,而是专门做了优化,不取值。count(*) 肯定不是 null,按行累加
按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*),所以我建议你,尽量使用 count(*)
16 order by