MySQL性能优化盲区(高并发情况下,事务内的数据先更新还是先查询?)

这篇具有很好参考价值的文章主要介绍了MySQL性能优化盲区(高并发情况下,事务内的数据先更新还是先查询?)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

近期看到了一个前阿里资深开发的学术分析视频:
高并发情况下,一个事务内有更新操作还有查询操作,那是先更新好,还是先无锁查询好?
仅70秒的视频,深感学问太深,但是海哥讲的有待补充,于是写下了这篇文章,作为补充。

鸣谢:前阿里资深开发极海Channel的技术分享。

先说答案

这是个开放性的问题,必须看业务场景,抛开业务场景谈架构设计,都是耍流氓。

  • 场景1:如果update语句的参数操作依赖于查询操作,那么必须先查询,再更新,否则update语句的参数都凑不齐。
  • 场景2:如果update语句的参数操作不依赖于查询操作,但两个操作的是一张表,业务强制要求select获取的数据必须是最新的,则也需要先更新再读取。
  • 场景3:以上两种情况除外,则优先考虑先查询再更新。

场景1受参数限制,顺序毋庸置疑。
场景2受业务限制,顺序毋庸置疑。
场景3是为了性能优化,才去选择的方案。

测试表

CREATE TABLE `cs` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `num` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '数字列',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `temp`.`cs` (`id`, `num`) VALUES (1, 1);
INSERT INTO `temp`.`cs` (`id`, `num`) VALUES (2, 2);
INSERT INTO `temp`.`cs` (`id`, `num`) VALUES (3, 3);


假设场景2的代码如下:
start transaction;
update cs set num = 13 where id = 1;
SELECT * FROM `cs`;
commit;


场景3的代码如下:
start transaction;
SELECT * FROM `cs`;
update cs set num = 13 where id = 1;
commit;

对场景2,同一个事务内,先执行update,事务没提交,能读取到最新的数据吗?

能。

步骤 SQL 补充
1 start transaction; 开启事务
2 select num from cs where id = 1; num值是1
3 update cs set num = 12 where id = 1; 更新num值为12
4 select num from cs where id = 1; num值是12
5 rollback; 回滚事务

都说不加锁的select是快照读,为什么select还能读取当前事务的最新数据?

根据现象反推,个人认为:
不加锁的select是快照读,针对的是事务之外的不加锁的select,MySQL RR的隔离级别,只要更新的事务未提交,其它事务就读取不到更改的新数据。
当前事务内的select,就是不加锁的当前读(个人称谓)。当然,真正的当前读概念是为了保证读的最新数据,必须加锁。

对场景3的性能优化原理分析

得知道4个前提:

  1. 场景3的实现,不会影响业务和开发。
  2. 因为select没有加S或X锁,所以不会阻塞。
  3. update语句会上X锁,可能是行锁、间隙锁,或者表锁(受索引、where条件的影响),所以并发请求过来后,其它事务的update有被阻塞的可能。
  4. 用事务,就需要InnoDB引擎,InnoDB引擎支持行级锁,如果确定update的X锁,在并发情况下锁定的范围没有交集,这种优化方式起不到作用,这意味着不会阻塞。
  • 如果先更新再查询:
    分析原理:
    事务A的update语句会上锁,并发情况下阻塞事务B的update操作,如果事务A的select是个慢查询,事务A的X锁释放需要等到事务提交,而不是update语句本身执行完毕,这就意味着事务A select的环节,X锁也未释放,从而阻塞其它事务的update,降低性能。
    实操模拟:
步骤 事务A 事务B 补充
1 start transaction; start transaction; 双方开启事务,模拟并发请求
2 update cs set num = 1234 where id = 1; update cs set num = 1234; 两个不同where范围的update,模拟线上的场景
3 / 阻塞 事务A的行X锁,阻塞了事务B的表X锁
4 select * from cs where id = 1; 阻塞 这一步很重要,优化就是为了避免这一步的阻塞耗时,特别是慢查询
5 commit; 阻塞 事务A提交
6 / select * from cs where id = 1; 事务A完成,事务B不会再阻塞了
7 / commit; 结束事务B
  • 如果先查询再更新:
    分析原理:事务A的select语句不会上锁,此时事务不会导致事务B阻塞,如果执行到事务A执行到update,才回去上X锁,直到事务提交锁资源释放,即使事务A的select是一个慢查询,也不会加大事务A释放锁资源的事件,进而减少事务B的阻塞时间。
    实操模拟:
步骤 事务A 事务B 补充
1 start transaction; start transaction; 双方开启事务,模拟并发请求
2 select * from cs where id = 1; select * from cs where id = 1; 两个事务不加锁不阻塞,这一步的阻塞时间省了
3 update cs set num = 1234 where id = 1; update cs set num = 1234; 两个事务更新
4 / 阻塞 两个X锁范围有冲突,阻塞
5 commit; 阻塞 事务A提交
6 / commit; 事务B提交

所以说,只要业务允许,调整SQL语句的执行顺序,高并发情况下,就能得到不小的性能提升,但是这一点很容易忽略。文章来源地址https://www.toymoban.com/news/detail-840179.html

到了这里,关于MySQL性能优化盲区(高并发情况下,事务内的数据先更新还是先查询?)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【性能优化】MySQL百万数据深度分页优化思路分析

            一般在项目开发中会有很多的统计数据需要进行上报分析,一般在分析过后会在后台展示出来给运营和产品进行 分页查看 , 最常见的一种就是根据日期进行筛选 。这种统计数据随着时间的推移数据量会慢慢的变大,达到百万、千万条数据只是时间问题。 一、数

    2024年02月15日
    浏览(48)
  • 数据库——MySQL高性能优化规范

    所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用 MySQL 保留(如果表名中包含查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过 32 个字符 临时库表必须以 tmp_为前缀并以日期为后缀,

    2024年02月11日
    浏览(99)
  • MySQL数据库进行性能优化的思路

    对MySQL数据库进行性能优化的思路可以涵盖以下方面: 索引优化: 索引是提高查询性能的关键。确保表中的关键列和经常用于查询条件的列都被适当地创建了索引。可以使用 CREATE INDEX 语句添加索引,或者使用 ALTER TABLE 语句在已有表上添加索引。例如,对于一个用户表中的

    2024年02月06日
    浏览(53)
  • MySQL数据库内存配置与性能优化:合理分配内存,提升数据库性能

             引言 :MySQL是广泛使用的关系型数据库管理系统,而合理配置数据库的内存是保障其高性能运行的关键之一.本文将介绍如何根据MySQL数据库内存值大小来定义,以及这样配置如何影响数据库的性能   内存配置的基本原则 : innodb_buffer_pool_size :该参数定义了InnoDB存储引擎

    2024年02月22日
    浏览(54)
  • 【MySQL】事务之MVCC(多版本并发控制)

    读-读 :不存在任何问题,也不需要并发控制 读-写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读 写-写 :有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失 多版本并发控制 ( MVCC )是一种用来解决 读

    2024年02月14日
    浏览(43)
  • MySQL - 并发控制与事务的隔离级别【头歌】

    目录 相关知识 并发操作可能产生的数据不一致性 MySQL的事务隔离级别 示例 第一关:并发控制与事务的隔离级别 编程要求 测试说明 代码如下 第二关:读脏 任务描述 相关知识 读脏 读脏产生的原因 编程要求 代码如下: 第三关:不可重复读 任务描述 相关知识 不可重复读

    2024年02月09日
    浏览(49)
  • MySQL——性能优化与关系型数据库

    吞吐与延迟:有些结论是反直觉的,指导我们关注什么。 没有量化就没有改进:监控与度量指标,指导我们怎么去入手。 80/20原则:先优化性能瓶颈问题,指导我们如何去优化。 过早的优化是万恶之源:指导我们要选择优化的时机。 脱离场景谈性能都是耍流氓:指导我们对

    2024年02月01日
    浏览(48)
  • MySQL数据库IO性能优化方法论

    作者:禅与计算机程序设计艺术 随着互联网信息化的发展,网站日益繁荣,用户对网站访问速度要求越来越高。如何提升网站数据库IO性能从而实现快速响应?本文将从数据库的优化角度出发,结合实际应用场景,进行系统地剖析、归纳和总结,为读者提供一个系统性、完整

    2024年02月06日
    浏览(51)
  • 高并发与性能优化的神奇之旅

    作为公司的架构师或者程序员,你是否曾经为公司的系统在面对高并发和性能瓶颈时感到手足无措或者焦头烂额呢?笔者在出道那会为此是吃尽了苦头的,不过也得感谢这段苦,让笔者从头到尾去探索,找寻解决之法。 目录 第一站:超越时间的加速法术 对此有何解决之法呢

    2024年02月14日
    浏览(40)
  • 高并发缓存实战RedisSon、性能优化

    对于经常访问的数据保留在redis缓存当中,不用带数据设置超时时间定期删除控制redis的大小 缓存击穿数据库没有被击穿 如果商家是批量导入的数据,呢么就会同时存到redis中,设置固定的时间就会导致缓存在一瞬间失效,用户访问不到就会将流量打到数据库上造成数据库段

    2024年02月13日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包