04 | 深入浅出索引(上)

2019-07-10 14:56:06

本文的总结源于林晓斌在极客时间里面的课程,为避免产生商业问题,我只是用于个人学习总结。
原文地址:https://time.geekbang.org/column/article/69236

小结

  1. 索引的作用:提高数据查询效率
  2. 常见索引模型:哈希表、有序数组、搜索树
  3. 哈希表:键-值(key-value)
  4. 哈希思路:把值放在数组里,用一个哈希函数把key换算成一个确定的位置,然后把value放在数组的这个位置
  5. 哈希冲突的处理办法:链表
  6. 哈希表适用场景:只有等值查询的场景
  7. 有序数组:按顺序存储。查询用二分法就可以快速查询,时间复杂度是:O(log(N))
  8. 有序数组查询效率高,更新效率低
  9. 有序数组的适用场景:静态存储引擎(比如往年数据,不会进行变动的数据)
  10. 二叉搜索树:每个节点的左儿子小于父节点,父节点又小于右儿子
  11. 二叉搜索树:查询时间复杂度O(log(N)),更新时间复杂度O(log(N))
  12. 数据库存储大多不适用二叉树,因为树高过高,在机械硬盘上带来查询效率,会适用N叉树
  13. InnoDB中的索引模型:B+Tree
  14. 索引类型:主键索引、非主键索引。主键索引的叶子节点存的是整行的数据(聚簇索引),非主键索引的叶子节点内容是主键的值(二级索引)
  15. 主键索引和普通索引的区别:主键索引只要搜索ID这个B+Tree即可拿到数据。普通索引先搜索索引拿到主键值,再到主键索引树搜索一次(回表)
  16. 一个数据页满了,按照B+Tree算法,新增加一个数据页,叫做页分裂,会导致性能下降。空间利用率降低大概50%。当相邻的两个数据页利用率很低的时候会做数据页合并,合并的过程是分裂过程的逆过程
  17. 从性能和存储空间方面考量,自增主键往往是更合理的选择

思考题

使用InnoDB创建的表T,如果你要重建索引k,你的两个SQL语句可以这么写:

alter table T drop index k;
alter table T add index(k);

如果你要重建主键索引,也可以这么写:

alter table T drop primary key;
alter table T add primary key(id);

对于上面这两个重建索引的作法,说出你的理解。如果有不合适的,为什么?更好的方法是什么?

03 | 事务隔离:为什么你改了我还看不见?

本文的总结源于林晓斌在极客时间里面的课程,为避免产生商业问题,我只是用于个人学习总结。 原文地址:https://time.geekbang.org/column/article/68963 思维导图 图形解说 针对上面看到的四个隔离级别,并结合这个案例来进行解说,我们来看看不同的隔离级别下,事务A会有哪些不同的返回结果,也就是图里面V1、V2、V3的返回值分别是什么 若隔离级别是“读未提交”,则V1的值就是2.这时候事务B虽然还没有提交,但是结果已经被A看到了。因此,V2、V3也都是2. 若隔离级别是“读提交”,则V1是1,V2的值是2.事务B的更新在提交后才能被A看到。所以V3的值也是2. 若隔离级别是“可重复读”,则V1、V2是1,V3是2.之所以V2还是1,遵循的就是这个要求:事务在执行期间看到的数据前后必须是一致的。 若隔离级别是“串行化”,则在事务B执行“将1改成2”的时候,会被锁住。直到事务A提交后,事务B才可以继续执行。

05 | 深入浅出索引(下)

本文的总结源于林晓斌在极客时间里面的课程,为避免产生商业问题,我只是用于个人学习总结。 原文地址:https://time.geekbang.org/column/article/69636 小结 覆盖索引:覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段 针对某些高频查询,要根据市民的身份证号查询他的姓名,则在(身份证号、姓名)上面创建一个联合索引,就可以在这个高频请求上用到覆盖索引,不再需要回表查整行记录,减少语句的执行时间 B+树这种索引结构,可以利用索引的“最左前缀”,来定位记录 联合索引的理解:比如一个联合索引(a,b,c),其实质是按a,b,c的顺序拼接成了一个二进制字节数组,索引记录是按该字节数组逐字节比较排序的,所以其是先按a排序,再按b排序,再按c排序,至于其为什么是按最左前缀匹配的也就显而易见了。 给表创建索引时,应该创建哪些索引,每个索引应该包含哪些字段,字段的顺序怎么排列,这个问题没有标准答案,需要根据具体的业务来做权衡。不过有些思路还是可供参考的: