首页 > 数据库 >MySQL锁、事务和索引

MySQL锁、事务和索引

时间:2024-04-15 16:48:42浏览次数:29  
标签:事务 重复 索引 MySQL table 主键 select

并发事务的控制方式是MVCC行锁

按范围分:表级锁页锁行级锁(锁一行或者多行)(记录索间隙锁临键锁(可重复读默认用这个做行锁,除非是主键和唯一索引会使用记录索))

按功能分:读锁(S)写锁(X)

意向锁表级锁,分为意向共享锁意向排他锁,用于协调表锁和行锁的关系,事务想要在某些行上加共享锁/排它锁,需要先取得意向共享/排他锁,这个是由数据库引擎自己维护的

插入意向锁是特殊的间隙锁,同种锁之间只要索引主键不冲突就不会阻塞

自增锁是用于自增主键的

 

数据库的隔离级别

读未提交(READ-UNCOMMITTED):最低的隔离级别,能读取到并发事务未提交的数据,会产生脏读、不可重复读、幻读

读已提交(READ-COMMITTED): 事务内,普通读能读到并发事务已经提交的数据,可以阻止脏读,会发生不可重复度和幻读

可重复读(REPEATABLE-READ):事务内,对同一行数据的普通读(非当前读),读到的数据是不变的

串行化(SERIALIZABLE):最高的隔离级别,完全服从ACID,事务依次诸葛执行,没有并发事务,能防止脏读、不可重复读、幻读

 

脏读:可以读取到别的事务还未commit的数据

不可重复读:在一个事务内,对同一数据的多次读取(普通读),结果不一致

幻读:在一个事务内,对同一范围的数据进行多次读取(普通读),会受到并发事务的插入和删除的影响,从而导致结果集不一致,可能多了几条数据,可能少了几条数据

 

普通读:select * from table

当前读(更新读):select * from table for update

 

 

MySQL默认是可重复读,PostgreSQL默认读已提交

 

MySQL的InnoDB的可重复读通过MVCC临键锁可以解决大部分的幻读,为什么是大部分呢,如下是一个例子

背景:InnoDB+可重复读

1. A开启事务,并执行sql:select * from table where id > 101,结果为0条数据

2. B开启事务,insert into table (id, name) values (101, 'aa'), 并提交事务

3. A执行sql: update table set name = 'bb' where id = '101', 可以修改

4. A执行sql: select * from table where id > 101,能查到101这条数据,并提交事务

虽然事务A一开始普通读查到的记录数为0,但是后续经过update以后,普通读能查到1条数据,就产生了幻读

 

 

MySQL的InnoDB+可重复读

插入:插入意向锁,特殊的间隙锁,同种锁之间只要索引主键不冲突就不会阻塞

更新:可能表锁(不走索引)、临键锁(普通索引)、记录锁(唯一索引/主键索引)

删除:可能表锁(不走索引)、临键锁(普通索引)、记录锁(唯一索引/主键索引)

更新读:可能表锁(不走索引)、临键锁(普通索引)、记录锁(唯一索引/主键索引)

 

InnoDB在可重复读的隔离级别下,因为使用了临键锁,把间隙给锁起来了,扩大了锁的范围,就容易发生死锁

死锁的例子

 

覆盖索引:就是select字段包含在索引内了,一般使用联合索引,将需要select的字段和一个需要做where条件的字段组成联合索引,就不会回表(因为普通索引会存主键和自身的索引值,所以select的字段都包含了,就不会回表了,本来会进行回表查询,先根据普通索引查到主键,然后根据主键再去找到select字段)

索引下推:一般是发生在联合索引中,where有多个条件,提前判断第二第三个条件,把不符合的记录直接过滤掉

在5.6之前的版本(没有索引下推),先判断第一个条件,满足就回表取回整行数据,然后再server层,server层再进行判断第二、第三个条件

例子:name 和age组成联合索引,select * from table where name like 'zh%' and age=10;  存储引擎会在取回数据前,就根据name和age进行了过滤,因为这里用的是select * ,所以是减少了回表的次数,如果是select name, age  就不会回表

 

标签:事务,重复,索引,MySQL,table,主键,select
From: https://www.cnblogs.com/huainanyin/p/18135278

相关文章

  • MySQL优化:索引
    1、谈一下你对于mysql索引的理解?(为什么mysql要选择B+树来存储索引)​ mysql的索引选择B+树作为数据结构来进行存储,使用B+树的本质原因在于可以减少IO次数,提高查询的效率,简单点来说就是可以保证在树的高度不变的情况下可以存储更多的数据:​ 1、在MYSQL的数据库中,表的真实数据和......
  • Mysql安装和远程登录--Centos7
    在Centos7中使用的包管理工具是yum,当然使用包管理工具安装也是最方便的。本文操作内容需要在root用户下,否则有些步骤无法成功执行。系统环境信息展示安装MySQL提供的RPMwgethttps://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm检查是否下载成功......
  • mysql的分区之key,hash分区
    1.hash分区HASH分区主要用来确保数据在预先确定数目的分区中平均分布,要做的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。hash分区所使用的字段一定要是主键!!createtable表名(.........)engine=MyISAMpartitionbyhash(算......
  • 淘宝二面:MySQL里有2000万条数据,但是Redis中只存20万的数据,如何保证redis中的数据都是
    引言在当今互联网领域,尤其在大型电商平台如淘宝这样的复杂分布式系统中,数据的高效管理和快速访问至关重要。面对数以千万计的商品、交易记录以及其他各类业务数据,如何在MySQL等传统关系型数据库之外,借助内存数据库Redis的力量,对部分高频访问数据进行高效的缓存处理,是提升整个系统......
  • mysql交换两列数据
    mysql交换两列数据某ai上居然给出了下面这个语句,这语句是错误的,会把两列换成一样的数据UPDATEt_aSETcol1=col2,col2=col1;下面的语句是可行的updatet_aasa,t_basbseta.col1=b.col2,a.col2=b.col1wherea.id=b.id;下面是使用临时变......
  • .net core EF mysql 共享事务
     .netcoreEFmysql共享事务在.NETCore中使用EntityFramework(EF)Core与MySQL一起工作时,您可以使用System.Transactions的TransactionScope来创建一个可以跨多个数据库连接共享的事务。以下是一个简单的示例,展示了如何在.NETCore应用程序中使用EntityFramewo......
  • MySQL概述以及MySQL的安装以及启动
    一、数据库的相关概念数据库Database,简称DB。按照一定的数据结构来组织、存储和管理数据的仓库。数据库管理系统DatabaseManagementSystem,一种操纵和管理数据库的大型软件,用于创建、使用和维护数据库,简称DBMS。  关系型数据库(RDBMS)概念:关系型数据库,是建立在关系模型......
  • 哪(个)些特性功能不用于数据的查询优化?() 并行查询 索引 视图 分区
    哪(个)些特性功能不用于数据的查询优化?()并行查询索引视图分区视图并不在数据库中以存储的数据值集形式存在,而仅仅是一个给用户展示的逻辑虚表,其在数据库中底层还是以完整的数据存储。数据的查询优化策略:避免全表扫描,采用分区的形式,找到指定区域来避免全表查询。建......
  • mysql中文全文索引的记录
    在MySQL5.7.6之前,全文索引只支持英文全文索引,不支持中文全文索引,需要利用分词器把中文段落预处理拆分成单词,然后存入数据库。从MySQL5.7.6开始,MySQL内置了ngram全文解析器,用来支持中文、日文、韩文分词。创建示例--创建表格CREATETABLEarticles(idINTAUTO_INCREME......
  • Mysql - 什么是三大范式(通俗详解)
    Mysql-什么是三大范式(通俗详解)高月之风关于数据的一切我都喜欢。​关注他 218人赞同了该文章​展开目录 Hello~我是高月!我将会在这篇文章中用通俗易懂的话为你简单说明什么是Mysql的三大范式。如果喜欢这篇文章,请点赞、关注......