加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡阳站长网 (https://www.0734zz.cn/)- 数据集成、设备管理、备份、数据加密、智能搜索!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL索引原理与应用:索引类型,存储结构与锁

发布时间:2019-06-04 23:35:38 所属栏目:MySql教程 来源:王下邀月熊_Chevalier
导读:在数据结构与算法--索引 https://url.wx-coder.cn/O07eI 一节中,我们讨论了 B+Tree, LSM-Tree 这样的文件索引以及全文索引的基础算法,本文则会针对文件索引在关系型数据库中的实际应用进行探讨。 索引(Index)是帮助数据库系统高效获取数据的数据结构,

MySQL 为我们提供了行锁、表锁、页锁三种级别的锁,其中表锁开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低。行锁开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高;页锁开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般。每个存储引擎都可以有自己的锁策略,例如 MyISAM 引擎仅支持表级锁,而 InnoDB 引擎除了支持表级锁外,也支持行级锁(默认)。

InnoDB 行锁是通过给索引上的索引项加锁来实现的,这一点 MySQL 与 Oracle 不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB 这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB 才使用行级锁,否则,InnoDB 将使用表锁,同样地,当 for update 的记录不存在会导致锁住全表。当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB 都会使用行锁来对数据加锁。

InnoDB 的加锁过程比较复杂,将所有扫描到的记录都加锁,范围查询会加间隙锁,然后加锁过程按照两阶段锁 2PL 来实现,也就是先加锁,然后所有的锁在事物提交的时候释放。加锁的策略会和数据库的隔离级别有关,在默认的可重复读的隔离级别的情况下,加锁的流程还会和查询条件中是否包含索引,是主键索引还是普通索引,是否是唯一索引等有关。

譬如对于 select * from o_order where order_sn = '201912102322' for update; 这条 SQL 语句,在不同的索引情况下其加锁策略也不一致:

MySQL索引原理与应用:索引类型,存储结构与锁

  • order_sn 是主键索引,这种情况将在主键索引上的 order_sn = 201912102322 这条记录上加排他锁。
  • order_sn 是普通索引,并且是唯一索引,将会对普通索引上对应的一条记录加排他锁,对主键索引上对应的记录加排他锁。
  • order_sn 是普通索引,并且不是唯一索引,将会对普通索引上 order_sn = 201912102322 一条或者多条记录加锁,并且对这些记录对应的主键索引上的记录加锁。这里除了加上行锁外,还会加上间隙锁,防止其他事务插入 order_sn = 201912102322 的记录,然而如果是唯一索引就不需要间隙锁,行锁就可以。
  • order_sn 上没有索引,innoDB 将会在主键索引上全表扫描,这里并没有加表锁,而是将所有的记录都会加上行级排他锁,而实际上 innoDB 内部做了优化,当扫描到一行记录后发现不匹配就会把锁给释放,当然这个违背了 2PL 原则在事务提交的时候释放。这里除了对记录进行加锁,还会对每两个记录之间的间隙加锁,所以最终将会保存所有的间隙锁和 order_sn = 201912102322 的行锁。
  • order_sn = 201912102322 这条记录不存在的情况下,如果 order_sn 是主键索引,则会加一个间隙锁,而这个间隙是主键索引中 order_sn 小于 201912102322 的第一条记录到大于 201912102322 的第一条记录。试想一下如果不加间隙锁,如果其他事物插入了一条 order_sn = 201912102322 的记录,由于 select for update 是当前读,即使上面那个事物没有提交,如果在该事物中重新查询一次就会发生幻读。
  • 如果没有索引,则对扫描到的所有记录和间隙都加锁,如果不匹配行锁将会释放只剩下间隙锁。回忆一下上面讲的数据页的结果中又一个最大记录和最小记录,Infimum 和 Supremum Record,这两个记录在加间隙锁的时候就会用到。

【编辑推荐】

  1. DBA大牛MySQL优化心得,语句执行加速就是这么简单!
  2. 达梦DM8新品发布 国产数据库迎来新的里程碑
  3. 成也数据库 败也数据库 Oracle 如何云渡劫?
  4. 6月数据库排行:PostgreSQL 和 MongoDB 分数罕见下降
  5. MySQL导致CPU消耗过大,如何优化
【责任编辑:庞桂玉 TEL:(010)68476606】
点赞 0

(编辑:衡阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读