高并发写入应避免自增ID瓶颈,改用UUID或雪花算法;批量插入控制500~2000行并显式事务;用INSERT替代UPDATE、冷热分离、延迟合并优化写扩散;调优Buffer Pool、Redo Log及SSD配置。

高并发写入场景下主键设计要避免自增ID瓶颈
在秒杀、抢券、日志采集等高频写入场景中,单机自增主键会成为性能瓶颈。InnoDB的自增锁(AUTO-INC Lock)是表级锁,在高并发INSERT时会导致线程排队等待,吞吐量骤降。
建议方案:
- 使用UUID(短格式)或雪花算法(Snowflake)生成分布式唯一ID,规避自增锁;注意UUID无序性对B+树插入性能的影响,可考虑用UUID_SHORT()或将时间戳前置的有序UUID
- 若仍用自增,可配合innodb_autoinc_lock_mode = 2(交错模式)(需binlog_format=ROW),大幅降低锁冲突,但要注意主从复制安全性
- 分库分表时,主键应含分片字段(如user_id % 4),避免全局唯一ID中心化依赖
批量写入必须绕过单条INSERT的开销
面试常问:“每秒1万订单怎么写入?”答“用INSERT INTO ... VALUES (...),(...),...”只是起点,真正关键在控制粒度与事务边界。
实操要点:
- 单次批量行数建议500~2000行:太少则网络/解析开销占比高;太多易触发max_allowed_packet限制或长事务阻塞
- 显式控制事务:BEGIN; 多个INSERT; COMMIT;,避免默认自动提交带来的频繁刷盘(innodb_flush_log_at_trx_commit=1时尤为明显)
- 禁用唯一索引/外键校验(仅限导入期):SET unique_checks=0; SET foreign_key_checks=0;,导入完成后再恢复
写扩散问题:避免高频UPDATE引发的连锁反应
高并发场景下,看似简单的UPDATE可能隐含巨大代价——比如“库存扣减”触发二级索引更新、MVCC版本链膨胀、Buffer Pool压力激增。
优化思路:
- 用INSERT替代UPDATE:例如记录库存变更流水表(item_id, delta, ts),再异步聚合计算最终值,变“行锁竞争”为“顺序追加”
- 冷热分离:高频更新字段(如view_count、like_count)单独建宽表,与主体信息表解耦,减少主表UPDATE频率
- 延迟合并:对非强实时场景(如排行榜分数),先写入Redis计数器,定时批量同步到MySQL,避开写高峰
硬件与配置不调优,再好的SQL也白搭
面试官常追问:“你们线上怎么扛住5000 QPS写入?”答案不能只谈SQL,要体现系统级意识。
- innodb_buffer_pool_size设为物理内存的70%~80%,确保热点数据常驻内存,减少磁盘随机写
- innodb_log_file_size × 2 ≥ 1小时峰值写入量,避免频繁checkpoint导致I/O抖动
- SSD是硬性要求,HDD在高并发写入下IOPS瓶颈明显;同时启用innodb_flush_method=O_DIRECT绕过OS缓存,防止双缓存放大写放大










