前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL入门详解(二)---mysql事务、锁、以及优化

MySQL入门详解(二)---mysql事务、锁、以及优化

作者头像
步履不停凡
发布于 2019-09-11 09:34:34
发布于 2019-09-11 09:34:34
1.2K00
代码可运行
举报
文章被收录于专栏:逸繁逸繁
运行总次数:0
代码可运行

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在一个商城系统中,用户执行购买操作,那么用户订单中应该加一条,库存要减一条,如果这两步由于意外只进行了其中一步那么就会发生很大的问题。而事务可以很好的解决这个问题。

事务是数据库处理操作,其中执行就好像它是一个单一的一组有序的工作单元。换言之在组内每个单独的操作是成功的,那么一个事务才是完整的。如果事务中的任何操作失败,整个事务将失败。

事务性质:

  • 原子性:确保工作单位中所有操作都成功完成;否则,事务被中止,在失败时会回滚到事务操作以前的状态。
  • 一致性:可确保数据库在正确的更改状态进行一个成功的提交事务。
  • 隔离性:使事务相互独立的操作。
  • 持久性:确保了提交事务的结果或系统故障情况下仍然存在作用。

TCL(事务控制语言):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
begin;
操作;
commit;

BEGINSTART TRANSACTION; #显式地开启一个事务
COMMIT;COMMIT WORK; #二者等阶。COMMIT会提交事务并使已对数据库进行的所有修改成为永久性的。未COMMIT的操作都存放在内存中,仅当前客户端可以查看到,其他客户端看不到,当前客户端关闭后就清空了
ROLLBACK;ROLLBACK WORK;  #二者等阶。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改
SET AUTOCOMMIT=0 #禁止自动提交 隐式开启事务
SET AUTOCOMMIT=1 #开启自动提交

事务并发的问题:

1.脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

2.不可重复读:事务A多次读取同一数据,事务B在事务A多次读取过程中,对数据作了更新并提交 ,导致事务A多次读取同一数据时结果不一致

3.幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条没有改过来,就好像发生了幻觉一样

各个隔离级别情况:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#查看隔离级别
select @@session.tx_isolation;
#设置隔离级别
set session transaction isolation level read uncommitted

隔离级别

脏读可能性

不可重复读可能性

幻读可能性

未提交读 READ UNCOMMITED

不可重复读 READ COMMITED

可重复读 REPEATABLE READ

串行化 SERIALIZABLE

数据库锁

mysql不同存储引擎支持不同锁机制,innodb支持表行级锁默认行级锁,memory采用表级锁,bdb采用页面锁支持表级锁。

表级锁:开销小,加锁快,不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。不支持事务。

页面锁:开销和加锁时间介于前后者之间,会出现死锁;锁定粒度介于前后者之间,并发度一般。

行级锁:开销大,加锁慢,会出现死锁;锁定粒度小,发生锁的冲突概率最低,并发度也最高。

表级锁:两种模式 共享锁(读锁)与独占锁(写锁,排他锁),表级锁引擎:MyISAM MEMORY

  • 共享锁:在读的时候上锁,所有人都可以访问不阻塞其他用户对同一表读请求,但阻塞同一表的写操作包括自己;自己如果加了读锁,更新访问其他表会提示错误;加了读锁之后不能再加写锁
  • 独占锁:上锁之后其他人不能访问,阻塞其他用户对同一表的读和写操作,独占锁优先级别高于共享锁;自己加了写锁可以读写表中记录,但更新访问其他表都会提示错误

MyISAM在执行查询语句时会自动给涉及的所有表加读锁,在执行更新操作前加写锁,这个过程一般不需要用户干预。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#加锁
lock tables table_name read [local];lock tables table_name write [local];
#多表加锁
lock tables table_name [table_name] read [local];lock tables table_name [table_name] write [local];
#释放锁
unlock tables;
#查询表级锁争用情况
show status like 'table%';
show status like '%lock%';当waited immediate值比较大是说明阻塞严重
show processlist; #查看哪些sql在在等待锁
show open tables; #当前被锁住的表以及锁的次数
#并发插入
myisam存储引擎有一个系统变量concurrent_insert.专门用以控制其并发插入行为,其值为NEVER0AUTO1(默认)ALAWAYS20:不允许并发插入 ,1:如果表中没有空洞(表中没有被删除的行)myisam允许在一个进程读表的同时,另一个进程从表尾插入记录,2:无论表中有没有空洞,都允许在表尾插入记录
#读写锁优先级
max_write_lock_count=1 #设置写锁的最多次数,当系统处理一个写操作后就会暂停写操作给读操作执行机会
#降低写操作优先级,给读操作更高优先级
low_priority_updates=1 sql_low_priority_updates=1 在用写操作时要加low_priority关键字#视场景而定,读场景更重要或更多时如此设置
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
如何优化表所?
concurrent_insert设置2,总是允许并发插入,但是要定期OPTIMIZE TABLE整理空间碎片;视情况设置写优先级;视情况设置写内存,解决批量插入数据(如新闻系统更新)场景中。

行级锁:引擎InnoDB,模式包含 共享锁(S),排它锁(X),意向共享锁(IS),意向排它锁(IX) 如果一个事务请求的锁模式与当前的锁兼容,innoDB就将请求的锁授予该事物;反之,如果两者不兼容,该事物就要等待锁释放

行级锁特点:innoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件(例如id)检索数据,innoDB才使用行级锁,佛则将使用表锁;意向锁是innoDB自动加的,不需要用户干预,对于写操作(insert update delete)innodb会自动给涉及数据加排它锁,对于select InnoDB不会加任何锁

排它锁(X)

意向排它锁(IX)

共享锁(S)

意向共享锁(IS)

排它锁(X)

冲突

冲突

冲突

冲突

意向排它锁(IX)

冲突

兼容

冲突

兼容

共享锁(S)

冲突

冲突

兼容

兼容

意向共享锁(IS)

冲突

兼容

兼容

兼容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#加锁
SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE #主动添加共享锁(S)
SELECT * FROM table_name WHERE ... FOR UPDATE #主动添加独占锁(X)

#释放锁
commit;或
rollback;
  1. 当使用行排他锁写数据时,其他人无法操作本条数据;
  2. 当给一条数据添加了排它锁,其他人对这条数据没有任何权限,但并不影响其他人对其他数据操作;
  3. 在InnoDB默认的隔离方式下,操作者不提交,操作数据只保存在内存里,另一用户可以查询,查询到的是旧值;
  4. 即使字段家里索引在使用时自己变了类型,索引失效会加表锁;

间隙锁:比如有124三个数据,操作>1的数据,此时添加3或者5都是不可以的,所以要明确范围防止间隙锁

如何优化行级锁:

  1. 尽量使用较低的隔离级别(新手忽略);精心设计索引,并尽量使用索引访问数据,使加锁更精确从而减少锁冲突的机会
  2. 选择合理的事务大小,小事务发生锁冲突的几率也小
  3. 给记录集手动加锁时,最好一次性请求足够级别的锁
  4. 尽量使用相等条件访问数据,这样可以避免间隙锁对并发插入的影响
  5. 对于一些特定事务,可以使用表锁提高速度并减少死锁可能

数据库优化操作

优化成本 硬件>系统配置>数据库表结构>SQL语句及索引

优化效果 SQL语句及索引<数据库表结构<系统配置<硬件

MySQL逻辑架构:

客户端->连接线程处理->查询缓存、分析器、优化器->存储引擎

索引底层实现:B树

myisam存储是数据的地址 innodb存储的是索引值,所以索引不宜过长

explain参数详解:

select语句执行顺序:执行顺序:先where...group by ... having 再 select ... from ... 再 distinct ... order by ... limit ...

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#使用方式:
explain select * from demo;
#参数:
#id 执行顺序
id相同时顺序从被查询表数据量少至多(都一样的话按照书写顺序),子查询时id由外到里自增,先执行大的
#select_type 查询中每个select子句的类型
SIMPLE:简单SELECT(不使用UNION或子查询)
PRIMARY:最外面的SELECT
UNION:UNION中的第二个或后面的SELECT语句
DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
UNION RESULT:UNION 的结果
SUBQUERY:子查询中的第一个SELECT
DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
DERIVED:派生表(FROM子句的子查询)
#table 本次查询的表名,或派生表
#type mysql在表中的访问类型
ALL: 遍历全表,目标不带索引
<
index: 遍历全表索引树
<
range: 检索给定范围的有索引的行,between、<>,不能用in会使索引失效
<
ref: 检索给定具体值并有索引的行
<
eq_ref: 检索给定具体值并是唯一索引的行
<
const: 表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数
<
system: 衍生查询中只有一条数据
<
NULL
#possible_keys 本查询可能用的索引
#key 本查询真实用的索引
#key_len 索引在内存中占的长度(轻易不要给varchar加索引)
#ref 指定的条件类型
#rows 当前语句查到的行数
#Extra 
Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
range checked for each record (index map: ):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。
Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息,代表性能不错
Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。
Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户,性能一般
Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BYDISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。
IMPOSSIBLE :不可能的where语句如where id=1 and id=2

mysql优化方法:

  1. 通过使用explain命令分析sql语句的运行效率
  2. 通过开启慢查询日志查看效率慢的sql语句

单多表sql优化手段:

  1. 给使用频繁的字段加索引,调整索引顺序最佳左前缀原则,删除多余干扰索引,调整查询条件对索引有干扰的语句放最后

多表sql额外优化手段:

  1. 小表驱动大表(小表在左边,where小表.x=大表.y)
  2. left join 给左边表加索引,right join 给右边表加索引

注意:

  1. 不要将索引作为函数参数或表达式的一部分,这样会让索引失效;索引不要进行类型转化否则失效
  2. 复合索引应该遵循最佳左前缀,不要用or,in,!= < >关键字否则失效
  3. 及时删除冗长,不常用的索引
  4. like查询时尽量不要使用左边%引起索引失效

系统级别优化:

  1. 主从复制,读写分离,负载均衡

其他优化:

  1. 选尽量小的数据类型,列设置not null,加unsigned不允许加正负这样可以使正数上线多一倍,存储时间最好用TIMESTAMP使用4个字节存储,大多数情况下没有枚举类型的必要,表的列不要太不要超过10个字段多影响内存数据类型小而简单
代码语言:javascript
代码运行次数:0
运行
复制
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-12-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
MySQL锁、加锁机制(超详细)—— 锁分类、全局锁、共享锁、排他锁;表锁、元数据锁、意向锁;行锁、间隙锁、临键锁;乐观锁、悲观锁
客户端发往MySQL的一条条SQL语句,实际上都可以理解成一个个单独的事务(一条sql语句默认就是一个事务)。而事务是基于数据库连接的,每个数据库连接在MySQL中,又会用一条工作线程来维护,也意味着一个事务的执行,本质上就是一条工作线程在执行,当出现多个事务同时执行时,这种情况则被称之为并发事务,所谓的并发事务也就是指多条线程并发执行。
寻求出路的程序媛
2024/06/24
19.8K5
MySQL锁、加锁机制(超详细)—— 锁分类、全局锁、共享锁、排他锁;表锁、元数据锁、意向锁;行锁、间隙锁、临键锁;乐观锁、悲观锁
MySQL中的锁(表锁、行锁,共享锁,排它锁,间隙锁)
在数据库中,除传统的 计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一 个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。本章我们着重讨论MySQL锁机制 的特点,常见的锁问题,以及解决MySQL锁问题的一些方法或建议。
兔云小新LM
2019/07/30
2.6K0
【MySQL】一文带你搞懂MySQL中的各种锁
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资( CPU 、
陶然同学
2023/10/14
2K0
【MySQL】一文带你搞懂MySQL中的各种锁
InnoDB实现了两种类型的行锁
另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。
用户7999227
2021/10/08
1.3K0
史上最全MySQL锁机制
因为数据也是一种供许多用户共享的资源,如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素,所以进一步学习MySQL,就需要去了解它的锁机制。
数据和云
2019/05/29
7180
MySQL高级9-锁
  锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除了传统的计算资源(CPU、RAM、i/O)的挣用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素,从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
Se7eN_HOU
2023/09/06
2570
MySQL高级9-锁
一文理解MySQL的锁机制与死锁排查
MySQL的并发控制是在数据安全性和并发处理能力之间的权衡,通过不同的锁策略来决定对系统开销和性能的影响。
全菜工程师小辉
2021/06/25
2.7K0
一文理解MySQL的锁机制与死锁排查
MySQL 锁
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
用户9615083
2022/12/25
1.3K0
MySQL 锁
【MySQL-25】万字总结<锁>——(全局锁&行级锁&表级锁)【共享锁,排他锁】【间隙锁,临键锁】【表锁,元数据锁,意向锁】
默认情况下,InnODB在 REPEATABLE READ事务隔离级别运行,InnoDB使用 临键锁 进行搜索和索引扫描,以防止幻读。(本次演示)
YY的秘密代码小屋
2024/09/09
2030
【MySQL-25】万字总结<锁>——(全局锁&行级锁&表级锁)【共享锁,排他锁】【间隙锁,临键锁】【表锁,元数据锁,意向锁】
mysql事务隔离级别详解和实战
设置innodb的事务级别方法是:set 作用域 transaction isolation level 事务隔离级别,例如~
sunsky
2020/08/20
8890
mysql事务隔离级别详解和实战
MySQL锁详解
转载自http://www.cnblogs.com/luyucheng/p/6297752.html
allsmallpig
2021/02/25
4520
MySQL中的锁
对于MyISAM的表锁,主要有以下几点 (1)共享读锁(S)之间是兼容的,但共享读锁(S)和排他写锁(X)之间,以及排他写锁之间(X)是互斥的,也就是说读和写是串行的。
爱撒谎的男孩
2019/12/31
1.3K0
Mysql锁相关锁的分类锁的适用场景MyISAM表锁MyISAM写阻塞读的例子MyISAM读阻塞写例子MyISAM并发插入MyISAM读写并发MyISAM锁调度调节MyISAM锁调度行为解决读写冲突的
锁类型/引擎 行锁 表锁 页锁 MyISAM 有 InnoDB 有 有 BDB(被InnoDB取代) 有 有 锁的分类 表锁:开销小,加锁快,不会死锁,粒度大,冲突率高,并发低。 行锁:开销大,加锁慢,会死锁,粒度小,冲突率低,并发高。 页锁:处于表锁和行锁之间,会死锁。 锁的适用场景 表锁:更适用于查询为主,按少量索引条件更新。 行锁:更适用于大量按索引并发更新少量不同数据,同时又有并发查询。 MyISAM表锁 查看锁争用相关参数:show status
Clive
2018/04/19
1.7K0
细说MySQL锁机制:S锁、X锁、意向锁…
好久没有深入地写文章了,这次来发一篇,通过mysql事物 | Joseph's Blog (gitee.io)和其他一些博客有感进行一些补充,InnoDB详解在下期发布
Karos
2023/06/14
8.5K0
细说MySQL锁机制:S锁、X锁、意向锁…
虾皮二面:MySQL 中有哪些锁?表级锁和行级锁有什么区别?
MyISAM 仅仅支持表级锁(table-level locking),一锁就锁整张表,这在并发写的情况下性非常差。
Guide哥
2022/11/07
9750
虾皮二面:MySQL 中有哪些锁?表级锁和行级锁有什么区别?
MySQL数据库:锁机制
当数据库中多个事务并发存取同一数据的时候,若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。MySQL锁机制的基本工作原理就是,事务在修改数据库之前,需要先获得相应的锁,获得锁的事务才可以修改数据;在该事务操作期间,这部分的数据是锁定,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。
全栈程序员站长
2022/06/29
1.6K0
MySQL数据库:锁机制
⑩⑦【MySQL】锁:全局锁、表级锁、行级锁
①表锁 :表共享读锁(read lock) / 表独享写锁(write lock)
.29.
2023/11/21
6430
⑩⑦【MySQL】锁:全局锁、表级锁、行级锁
mysql之事务 锁(三)
事务:数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;事务是一组不可再分割的操作集合(工作逻辑单元); 典型事务场景(转账):
周杰伦本人
2022/10/25
3980
mysql之事务 锁(三)
MySQL锁分类
每次在听别人说锁的时候,是不是会有点儿晕?(一会儿排它锁,一会儿GAP锁...)因为你站在不同的角度来说,它的名字就会不同。根据我们DB的引擎、隔离级别不同,导致的锁的情况也会不同。
chengcheng222e
2021/11/04
3940
你需要了解关于MySQL锁的知识点,都列在这里了!
大概几个月之前项目中用到事务,需要保证数据的强一致性,期间也用到了mysql的锁,但当时对mysql的锁机制只是管中窥豹,所以本文打算总结一下mysql的锁机制。
Java宝典
2021/01/14
9120
你需要了解关于MySQL锁的知识点,都列在这里了!
相关推荐
MySQL锁、加锁机制(超详细)—— 锁分类、全局锁、共享锁、排他锁;表锁、元数据锁、意向锁;行锁、间隙锁、临键锁;乐观锁、悲观锁
更多 >
目录
  • MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在一个商城系统中,用户执行购买操作,那么用户订单中应该加一条,库存要减一条,如果这两步由于意外只进行了其中一步那么就会发生很大的问题。而事务可以很好的解决这个问题。
  • 事务是数据库处理操作,其中执行就好像它是一个单一的一组有序的工作单元。换言之在组内每个单独的操作是成功的,那么一个事务才是完整的。如果事务中的任何操作失败,整个事务将失败。
  • 事务性质:
  • TCL(事务控制语言):
  • 数据库锁
  • 数据库优化操作
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档