0

0

mysql并发访问如何减少锁冲突_mysql设计优化方法

P粉602998670

P粉602998670

发布时间:2026-01-02 11:04:44

|

538人浏览过

|

来源于php中文网

原创

SELECT ... FOR UPDATE 在高并发下易锁表,因其在满足条件的行上加排他锁,若无索引则升级为表级锁或锁整个索引范围,且事务间更新顺序不一致易致死锁;应确保WHERE字段有有效索引、避免混合操作、缩短事务、优先用INSERT ... ON DUPLICATE KEY UPDATE,并根据读写比例选择合适隔离级别。

mysql并发访问如何减少锁冲突_mysql设计优化方法

为什么 SELECT ... FOR UPDATE 在高并发下容易锁表?

本质是它会在满足条件的行上加排他锁(X锁),如果查询没走索引,InnoDB 会升级为表级锁或锁住整个索引范围;更常见的是多个事务按不同顺序更新同一组行,导致死锁或长时间等待。

  • 必须确保 WHERE 条件字段有有效索引,否则会触发全表扫描+间隙锁
  • 避免在事务中混合执行 SELECT ... FOR UPDATE 和非关联的 UPDATE,顺序不一致极易引发死锁
  • 尽量缩短事务生命周期:查完立刻更新,不要在事务里做 HTTP 调用、日志写入等耗时操作

INSERT ... ON DUPLICATE KEY UPDATE 替代“先查后更”逻辑

典型场景如计数器、状态机流转、幂等插入——这类操作若拆成 SELECT + INSERT/UPDATE,在并发下必然出现竞态:两个事务同时查到旧值,都执行更新,最终只生效一次。

INSERT INTO user_login_log (user_id, login_time, ip)
VALUES (123, NOW(), '192.168.1.1')
ON DUPLICATE KEY UPDATE login_time = VALUES(login_time), ip = VALUES(ip);
  • 前提是 user_id 或组合字段有唯一索引(如 UNIQUE KEY (user_id)
  • 注意 VALUES(col) 引用的是本次 INSERT 中该列的值,不是原记录值
  • 不支持在 ON DUPLICATE KEY UPDATE 子句中使用子查询,复杂逻辑需另寻方案

读多写少场景下,用 READ COMMITTED 隔离级别降低锁粒度

MySQL 默认隔离级别 REPEATABLE READ 会启用间隙锁(Gap Lock)防止幻读,但代价是更大范围的锁冲突;而 READ COMMITTED 只对实际命中的记录加行锁,不锁间隙,适合订单查询、商品详情等以读为主、写频次低的业务。

10Web
10Web

AI驱动的WordPress网站自动构建器,托管和页面速度助推器

下载
  • 修改方式:SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; 或在配置文件中设 transaction_isolation = 'READ-COMMITTED'
  • 副作用:可能读到“不可重复读”,但多数 Web 应用对此不敏感
  • 无法解决写-写冲突,仍需靠主键/唯一键约束 + 原子语句控制

分库分表前,先确认是不是索引和语句本身的问题

很多团队一遇到并发慢就想着分片,结果发现慢查询日志里全是 type: ALLExtra: Using filesort —— 根本问题在缺失索引或 ORDER BY/GROUP BY 没利用索引。

  • EXPLAIN FORMAT=TRADITIONAL 看执行计划,重点关注 keyrowsExtra
  • 复合索引要遵循最左匹配,比如 (a,b,c) 支持 WHERE a=1 AND b>2,但不支持 WHERE b=2
  • pt-query-digest 分析慢日志比肉眼扫更可靠,尤其能暴露低频但高延迟的“隐形杀手”语句

真正需要分片的信号是单表超千万行且写入持续增长、二级索引维护成本明显上升,而不是单纯因为某条 UPDATE 偶尔锁了 200ms。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

653

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

244

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

280

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

513

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

250

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

384

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

523

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

595

2023.08.14

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.6万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 779人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号