mysql 学习笔记 04-08

04 索引

索引的常见模型

哈希表、有序数组和搜索树。

哈希表这种结构适用于只有等值查询的场景

有序数组索引只适用于静态存储引擎

 

InnoDB 使用了 B+ 树索引模型,所以数据都是存储在B+ 树中的

B+ 树能够很好地配合磁盘的读写特性,减少单次查询的磁盘访问次数

基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。

主键长度越小,普通索引的叶子节点就越小,普通索引占用的空间也就越小

 

05 索引

回到主键索引树搜索的过程,我们称为回表

避免回表的方法

  1. 覆盖索引-SELECT 主键  

06 锁

MySQL 里面的锁大致可以分成全局锁、表级锁和行锁三类

表级锁

另一类表级的锁是 MDL(metadata lock)。

当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁。

 

行锁

MyISAM 引擎就不支持行锁

在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。

 

07 行锁

行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。

所以一个事务中需要锁多个行,可以把冲突最多的锁往后放。

死锁

死锁出现后两种策略

  • 等待超时 innodb_lock_wait_timeout
  • 发起死锁检测。发现死锁后,主动回滚一个事务。

一般都是第二种,但是时间复杂度O(n) 消耗大量cpu

解决办法:

确保业务不会出现死锁

控制并发度-对于相同行的更新,在进去引擎之前排队。

或者从设计上优化-将一行改多行,减小一行的冲突,这样需要业务逻辑上详细设计。

 

08事务隔离

快照 mvcc如何工作

InnoDB 里面每个事务有一个唯一的事务 ID,叫作 transaction id。它是在事务开始的时候向 InnoDB 的事务系统申请的,是按申请顺序严格递增的。

数据表中的一行记录,其实可能有多个版本 (row),每个版本有自己的 row trx_id。

不同版本之间通过 undo log(回滚日志)来计算得出。

 

每个事务或者语句有自己的一致性视图。普通查询语句是一致性读,一致性读会根据 row trx_id 和一致性视图确定数据版本的可见性。

更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(current read)。

你可能感兴趣的:(mysql,mysql)