mysql 索引概念以及使用方式

mysql相关总结

myisam 和 innoDB 的特点

myisam

myisam引擎 是mysql5.1之前的默认引擎,支持全文索引,压缩,空间函数。
不支持事务和行级锁,比较适合大批量插入,少量查询的场景,不支持外键,索引和数据是分开存储的。

innoDB

基于聚餐索引建立,支持事务,外键,通过MVCC 支持高并发,索引和数据存放在一起。

mysql 索引分类

按数据结构上来说,分为B+树和Hash 索引

如果对于数据库来说,二次回表查找的数据过多,导致性能低于全表扫描,MySQL可能会放弃使用索引
辅助索引(二级索引)会导致回表。

B+树

是一个有序的树结构,左大右大,非叶子节点仅存储id索引列,如果没有定义id索引列,那么会选择一个非空的唯一索引,如果还不存在,那么会默认隐式的定义一个主键作为聚簇索引。

索引的使用注意

覆盖索引,回表

mysql 锁类型

读锁
通过lock in share mode, 只能读,不能写

写锁
写锁为拍他锁,会阻塞读写操作。
从范围粒度上来讲,可以分为行级锁,表级锁,表锁会锁定整张表,并阻塞其他用户对于该表的读写操作,例如alter table 就会锁表。
行锁分为乐观锁,悲观锁,悲观锁通过 for update 实现,乐观锁通过版本号实现。

事务的基本特性和隔离级别

事务的基本特性,ACID, 原子性,一致性,隔离性,持久性。

隔离性有四个隔离级别。
ru(read uncommit) 读未提交,会产生脏读,会读到其他事务未提交的数据。
rc(read commit) 读已提交,在同一个事务中两次读取到不同的数据,产生不可重复读。
rr(repeated read) 默认的隔离级别,可能会产生幻读。在下次读取的时候删除了还能读到。
s (seriable) 顺序读,对于每一个读取都加表锁。不常用。

ACID 的实现方式

A: 由undo log 实现,记录了需要回滚的日志信息,事务会滚时,撤销已经执行成功的sql。
C: 一般由代码层面实现
I: 由MVCC 保证实现
D: 由 redo log 实现,持久性由 内存+redo log 实现。
mysql 修改数据,同时在内存和磁盘记录这次操作,事务提交的时候, 通过redo log 刷盘,宕机的时候通过redo log 恢复。

什么是幻读,什么是MVCC

说幻读,熟悉了解MVCC(多版本并发控制), 实际就是保存了数据在某个节点的快照。
在每一行数据,隐藏了两行,创建时间版本号,过期时间版本号码。 create_version, delete_version
每开始一个新事务,版本好都会递增,

mvcc 的查询原理为,查询创建版本号 小于等于当前事务版本号,删除版本号为null,大于当前版本。

间隙锁

间隙锁是 rr 隔离级别下才会产生的,结合MVCC 和 间隙锁 可以解决幻读的问题

间隙锁 没有互斥性,所以可能存在死锁问题。

唯一索引是不会有间隙索引的。

索引字段上的等值查询会升级为行锁, 所以尽量用等值查询

参考资料:

博客
https://www.cnblogs.com/itwild/p/13703259.html

美团博客
https://tech.meituan.com/2014/06/30/mysql-index.html
https://tech.meituan.com/2018/05/20/sql-parser-used-in-mtdp.html
https://tech.meituan.com/2014/08/20/innodb-lock.html

https://tech.meituan.com/tags/mysql.html

掘金

https://juejin.im/post/6869029652623523848
https://juejin.im/post/6870904502476603399
https://juejin.im/post/6868270408534720525

posted @ 2020-10-09 10:28  jzczer  阅读(146)  评论(0编辑  收藏  举报