mysql在高并发场景中的索引优化策略

发布时间 - 2026-01-09 00:00:00    点击率:
根本原因是非唯一二级索引导致间隙锁或临键锁,即使有索引也会锁住大范围;应优先用UNIQUE索引、避免高频字段单独建索引、用联合索引优化,并确保INSERT...ON DUPLICATE KEY UPDATE仅依赖单一唯一索引。

为什么 SELECT ... FOR UPDATE 会卡住,而加了索引也不行?

根本原因不是没加索引,而是加了「非唯一二级索引」却没覆盖查询条件,导致 MySQL 退化为间隙锁(Gap Lock)或临键锁(Next-Key Lock),锁住一大片范围。比如 WHERE status = 1,即使 status 有索引,若该值重复率高,InnoDB 仍可能锁住多个索引项及其间隙。

  • 优先用 UNIQUE 索引替代普通二级索引,让 FOR UPDATE 尽可能走唯一查找,只锁单行
  • 避免在高频更新字段(如 statusversion)上建单独索引,改用联合索引前置该字段 + 主键或高频过滤字段
  • 执行 EXPLAIN 确认是否走了索引,特别注意 keyrows 列;若 rows 远大于实际匹配数,说明索引选择性差

INSERT ... ON DUPLICATE KEY UPDATE 的索引依赖和死锁风险

这个语句本质是先按唯一约束(主键或 UNIQUE 索引)查找,再决定插入或更新。如果唯一约束不明确、或存在多个 UNIQUE 索引,MySQL 可能加锁顺序不一致,引发死锁。

  • 必须确保冲突检测只依赖**一个明确的唯一索引**,不要同时定义多个 UNIQUE 约束(如 emailphone 都设 UNIQUE
  • 联合唯一索引要严格按查询顺序定义,例如常用 INSERT ... ON DUPLICATE KEY UPDATE 基于 (tenant_id, biz_id),就建 UNIQUE KEY uk_tenant_biz (tenant_id, biz_id),别反过来
  • 高并发下,该语句仍可能因锁等待超时报 Deadlock found when trying to get lock,需在应用层重试,但重试前建议加随机微小延迟(如 1–10ms)

联合索引的最左匹配失效:为什么 WHERE a = ? AND c = ? 没走索引?

当联合索引是 (a, b, c),而查询跳过中间列 b,MySQL 无法使用 c 部分做索引查找,只能用到 ac 变成回表后过滤。

CREATE INDEX idx_abc ON orders (user_id, status, created_at);
  • WHERE user_id = 123 AND status = 1 → 走索引,且 status 可用于范围裁剪
  • WHERE user_id = 123 AND created_at > '2025-01-01'created_at 不生效,需回表后过滤
  • 对策:把高频等值查询字段放最左,范围查询字段放最右;必要时拆成两个索引,比如补一个 (user_id, created_at)

高并发写入时,自增主键为何比 UUID 更稳?

UUID(尤其无序版本如 UUID_SHORT() 或字符串 UUID)会导致聚簇索引频繁页分裂,B+ 树节点反复重排,产生大量磁盘随机写和锁竞争。而 BIGINT AUTO_INCREMENT 是严格递增的,新记录总追加到 B+ 树最右叶子页,写放大最小。

  • 不要用 CHAR(36) 存 UUID 作主键,哪怕加了索引,写入吞吐也会掉 30%+(实测 5k QPS 场景下)
  • 若业务强制需要分布式唯一 ID,优先选有序类方案:Twitter SnowflakeLeaf-segment 或 MySQL 8.0+ 的 UUID_TO_BIN(UUID(), true)(true 表示 compact mode)
  • 自增主键记得设足够大的类型,BIGINT UNSIGNEDINT 更安全,避免某天凌晨突然主键溢出
索引不是越多越好,真正关键的是让每条慢查背后的 WHEREORDER BYGROUP BY 都落在一个高效索引的最左前缀上;而高并发下,锁粒度、写入顺序、唯一性保障,往往比“能不能查得快”更致命。


# mysql  # ai  # twitter  # 为什么  # 分布式  # for  # select  # 字符串  # char  # int  # 并发  # 主键  # 死锁  # 多个  # 也会  # 锁住  # 根本原因  # 重试  # 的是  # 走了  # 一二级 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 音乐网站服务器如何优化API响应速度?  如何用虚拟主机快速搭建网站?详细步骤解析  如何用PHP快速搭建CMS系统?  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  Laravel如何使用Eloquent进行子查询  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  轻松掌握MySQL函数中的last_insert_id()  iOS发送验证码倒计时应用  Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑  laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法  如何快速搭建高效简练网站?  Internet Explorer官网直接进入 IE浏览器在线体验版网址  Laravel如何实现数据库事务?(DB Facade示例)  如何挑选高效建站主机与优质域名?  如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】  焦点电影公司作品,电影焦点结局是什么?  如何在腾讯云服务器快速搭建个人网站?  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  Python3.6正式版新特性预览  b2c电商网站制作流程,b2c水平综合的电商平台?  如何快速搭建二级域名独立网站?  JS弹性运动实现方法分析  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  如何快速查询网址的建站时间与历史轨迹?  在centOS 7安装mysql 5.7的详细教程  Laravel如何使用Blade模板引擎?(完整语法和示例)  如何快速搭建个人网站并优化SEO?  如何快速上传建站程序避免常见错误?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  Laravel如何实现API版本控制_Laravel版本化API设计方案  java ZXing生成二维码及条码实例分享  如何确保FTP站点访问权限与数据传输安全?  济南网站建设制作公司,室内设计网站一般都有哪些功能?  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  香港服务器部署网站为何提示未备案?  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程  Bootstrap整体框架之CSS12栅格系统  Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册  长沙做网站要多少钱,长沙国安网络怎么样?  Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID  如何用IIS7快速搭建并优化网站站点?  大同网页,大同瑞慈医院官网?  Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面  Laravel如何创建自定义中间件?(Middleware代码示例)  如何使用 jQuery 正确渲染 Instagram 风格的标签列表  C#如何调用原生C++ COM对象详解  HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】  Laravel如何实现模型的全局作用域?(Global Scope示例)  高端云建站费用究竟需要多少预算?