事务隔离级别与锁的对应关系_Mysql索引结构

事务隔离级别与锁的对应关系_Mysql索引结构1.隔离级别 1.1未提交读(read uncommit) RU 这是最低级别的隔离等级: 在这种隔离级别下,可以读取未提交的事务修改/更新到的数据,基本无数据库会选择该隔离级别 事务一 selec…

事务隔离级别、锁、索引、存储引擎

1.隔离级别

1.1未提交读(read uncommit) RU

这是最低级别的隔离等级

在这种隔离级别下,可以读取未提交的事务修改/更新到的数据,基本无数据库会选择该隔离级别

事务一 

select * from 表A where id = 1 读取到 name = 张三

代码100分

事务二

代码100分
update 表A set name = "李四" where id = 2

事务一

select * from 表A where id = 1 读取到 name = 李四

(然后事务二被回滚)

数据库里为”张三”,但是读取为李四,所以为”脏”读

    左边是事务1,先查一次,查到id为1的数据name为张三,这时候事务2又来了,把张三改成了李四,然后事务1又进行了一次查询,查出来了name为李四,那么假如这时候事务2发生了回滚,也就是name还是张三,但是事务1却读到了李四,这就是脏读

1.2已提交读(read commit) RC

oracle和mysql的默认隔离级别

在已提交读的情况下,虽然未提交的事务数据不会读取到,但是在这种情况下,会由于事务的执行也是需要时间的,在一个事务的两次相同查询间隔期间,存在其他事务提交,对数据库的数据进行了删除或者插入,那么这一个事务的两次查询结果就不一致了,这就是不可重复读。

1.2.1如何避免不可重复读:

mysql:

这里必须提到mysql的并发控制策略(锁策略)——共享锁和排他锁,见另一标题(mysql锁介绍)。

基于MyISAM引擎表在执行查询前,会自动执行表的加锁、解锁操作,一般情况下不需要用户手动加、解锁,但是有的时候也需要显式加锁,例如上文中存在的同一个事务中的两次关联紧密查询。

形如:

代码100分
lock tables ynst_fgfc_sum_app_dq_rlt_anls read,ynst_fgfc_count read;

select * from ynst_fgfc_sum_app_dq_rlt_anls;

select * from ynst_fgfc_count;

unlock tables;

1.3可重复读(repeatable read) RR

该情况解决了不可重复读的问题,但是存在幻读的问题,也就是在一个事务的两次查询过程中,存在更新和删除语句,查询出来的记录存在误差,给人一种幻觉,说起来和不可重复读基本一致,但是不可重复读针对的是数据库的更新和删除操作,幻读针对的是插入操作。

1.3.1串行化serializable

最高级别隔离,所有的事务都是顺序执行的,不存在并行的情况,所以也就不会出现脏读,幻读和不可重复读,但是这样肯定是降低了数据库执行效率的。

1.3.2事务隔离实现方案

LBCC

适用于读多写少的使用场景,在事务执行时锁定所有关联资源,读取时给数据加上共享锁,不允许其他事务给数据加上排他锁,写入时给数据加上排他锁,不允许其他任何锁的添加,执行完成之后进行锁的释放。

MVCC

适用于写多读少的使用场景,引用涉及到了快照的概念,大致理念是在事务的第一次查询是通过数据库innodb引擎内部给表添加的DB_TRX_ID(事务id)字段和DB_ROLL_PTR(回滚指针)给数据添加快照,其他事务改变数据时会给这两个字段进行填充,涉及到的事务通过这两个字段的填充值在解析sql时添加条件从而达到事务涉及数据不变的效果。

2.mysql锁介绍

锁的开销是较为昂贵的,锁策略其实就是保证了线程安全的同时获取最大的性能之间的平衡策略。

共享锁:

共享锁又称读锁,即多个连接可以共享读取同一条数据,但仅限于读取时使用,在没有排他锁加在资源上时,读锁是可以协调所有资源的,读锁之间不互相阻塞。

排他锁:

排他锁又称写锁,即当进行写入操作时,将当前表/当前行数据进行锁定,阻止其他的事务对表/行进行写入/读取,注意排他锁会阻塞所有相关的事务对数据的写入和读取,所以优先级是高于读锁的。这里有两个策略,一个是表锁,一个是行锁,mysql的基本锁策略默认使用的表锁:

  1. 表锁,顾名思义,锁住当前整个表,开销最小。

  2. 行锁,锁住当前事务所设计的表,一般是在存储引擎底层使用,开销最大

(这里的开销指的是系统对锁的管理,如果系统分配太多资源管理锁,自然会导致性能下降)

2.1锁使用场景

以一个sql举例:

update from 表A set columnA = "张三" where columnB = 1;

如果columnA存在索引,查询时会对匹配行进行锁定,不存在索引时进行锁表。

上面的太简单了:

实际上如何分析加锁,首先应该了解三点:

  1. 隔离级别(上面有提到)

  2. 索引和执行计划https://www.jianshu.com/p/7a0c215edb1d

  3. sql中字段是否含有索引

2.1.1锁使用情况查询

select * from information_schema.innodb_locks

查看数据库锁的使用情况(innodb引擎)

select * from information_schema.innodb_lock_waits

3.索引类型

1.普通索引,查询时会用到的,并不要求唯一性的常用索引

create index ynst_fgfc_sum_app_dq_rlt_anls_DAY_FG_CNT_uindex

on ynst_fgfc_sum_app_dq_rlt_anls (DAY_FG_CNT);

2.唯一索引(关键字unique),要求涉及到的列/组合列唯一,可以包含空值,和主键不一样,主键是唯一索引加上字段不为空限制

create unique index ynst_fgfc_sum_app_dq_rlt_anls_DAY_FG_CNT_uindex

on ynst_fgfc_sum_app_dq_rlt_anls (DAY_FG_CNT);

3.全文索引(关键字FULLTEXT),在mysql3.2版本加入,但是在mysql5.7.6才支持中文全文索引,只能在VARCHER,VACHER2,TEXT类型的字段上加索引。

添加索引:

alter table ynst_fgfc_sum_app_dq_rlt_anls add fulltext testIndex(PRO_CODE);

直接创建索引:

create fulltest index on ynst_fgfc_sum_app_dq_rlt_anls (PRO_CODE)

注意: 1:先导入数据再创建全文索引比后导入数据再创建索引要快很多

2:目前全文索引值支持MyISAM和InnoDB两种存储引擎

索引的作用是为了加快查询速度,所以在使用索引优化数据库的同时

一方面是需要让sql命中索引(暂放)

一方面也需要明确索引的使用场景,给表加上索引会降低数据的更新速度,执行更新操作之后数据库需要对索引文件进行保存操作,数据量过大会带来时间上的损耗,索引文件一般不会很大,但是在大数据量+组合列索引的情况下会比较严重,它会大幅占用磁盘空间。

4.存储引擎

数据库默认的存储引擎是InnoDb

除此之外还有MyISAM存储引擎

MEMORY存储引擎(瞬态,非重要的数据,数据服务重启后丢失)

MERGE存储引擎

CSV存储引擎

InnoDB与MyISAM最大不同有两点:

  1. 支持事务
  2. 采用行级锁

具体见官网说明

https://dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html

查询资料:

  1. 深入分析MySQL中事务以及MVCC的实现原理

https://baijiahao.baidu.com/s?id=1669272579360136533&wfr=spider&for=pc

  1. mysql索引总结

https://www.jianshu.com/p/7a0c215edb1d

  1. 深入理解mysql——锁、事务和并发控制

https://zhuanlan.zhihu.com/p/36060546

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/7043.html

(0)
上一篇 2023-03-28
下一篇 2023-03-28

相关推荐

  • mysql生产环境运维方案_生产环境和正式环境

    mysql生产环境运维方案_生产环境和正式环境第一次写博客,有漏洞的地方希望大佬指正 背景:优化公司老系统中的一条慢sql,查看执行过程如下: sql虽然比较简单,平时执行也没发现什么问题,但一到生产环境系统频繁调用,问题就显现出来了,整个系统停

    2023-02-03
    152
  • 使用 Python 输入整数的方法

    使用 Python 输入整数的方法计算机科学的许多应用需要输入整数,Python 中有多种方法可以输入整数。在本篇文章中,我们将介绍 Python 中输入整数的方法,并提供代码示例,帮助读者更好地理解。

    2024-07-21
    38
  • 聊聊荣耀30S 5G手机到底值不值得买?

    聊聊荣耀30S 5G手机到底值不值得买?     最近和群里不少小伙伴聊了聊荣耀30S的问题,很多人都在问荣耀30S 5G手机值不值得买?我的答案是肯定的。有钱买苹果、买三星,那都是梦里,现实生活的人们都是希望在有限的预算中购买到性价比最…

    2023-02-13
    144
  • Thinkphp5中打印最后一条SQL语句「建议收藏」

    Thinkphp5中打印最后一条SQL语句「建议收藏」最近用到thinkPHP5链表查询比较多,但是链表查询如何打印sql语句怎么试都不对,所以研究了一下usethinkDb;dump(Db::table(‘table_name‘)->getLastS…

    2023-04-05
    154
  • Python模块:Numpy计算数组

    Python模块:Numpy计算数组Numpy是Python中功能强大的库之一,它为Python提供了一种更高效的方法来处理大型数​​组和矩阵。Numpy使得Python变得更接近于一种与MATLAB和R等科学计算语言相似的语言,使其在科学计算和数据分析方面更有竞争力。它具有广泛的功能和易于使用的API,允许开发人员更快地进行数值计算。

    2024-03-06
    90
  • 输入多个数字

    输入多个数字在计算机编程中,输入多个数字是一个常见的需求。它可以用来处理各种问题,例如求平均值,排序等等。

    2024-08-06
    36
  • PHP程序员如何做好MySQL数据库优化

    PHP程序员如何做好MySQL数据库优化1.使用MyISAM而不是InnoDB MySQL有很多数据库引擎,但是你最可能碰到的就是MyISAM和InnoDB。 MySQL默认使用的是MyISAM。但是,很多情况下这都是一个很糟糕的选择,除…

    2023-03-15
    148
  • 数据库的常用命令_数据库执行命令

    数据库的常用命令_数据库执行命令1. 数据操作类语句: SELECT:从数据库表中检索数据行和列 INSERT:把新的数据表记录添加到数据库中 DELETE:从数据库中删除数据记录,针对数据进行操作 UPDATE:修改现有数据库中的

    2023-05-30
    149

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注