高 并发 sql 优化核心在应用层设计与 SQL 精简,需合理建索引(遵循最左前缀)、缩短事务、精简查询、善用缓存与读写分离,并通过 EXPLai N 分析执行计划。

SQL 高并发场景下,性能瓶颈 往往不在 数据库 硬件,而在 SQL 写法、索引设计和事务控制。真正有效的优化,80% 来自应用层的合理设计和 SQL 本身的精简,而不是盲目升级服务器或加缓存。
用好索引,但别乱建
索引不是越多越好,而是要匹配高频查询条件和排序字段。联合索引要注意最左前缀原则——比如建了 (user_id, status, create_time),那 WHERE user_id = ? AND status = ? 能用上,但只查 status = ? 就失效了。删除长期不用的索引,每个额外索引都会拖慢写入速度。
- 用 EXPLAIN 看执行计划,重点观察 type(尽量到 ref/const)、key(是否命中索引)、rows(扫描行数越少越好)
- 区分等值查询和范围查询:等值字段放联合索引前面,范围字段(如 >、BETWEEN)放后面
- 避免在索引列上做函数操作,比如 WHERE YEAR(create_time) = 2024 会让索引失效,改用 create_time >= ‘2024-01-01′ AND create_time 2025-01-01’
减少锁冲突,缩短事务生命周期
高并发下,长事务是死锁和等待超时的主因。事务不是“开始—结束”越长越好,而是越短、越聚焦越好。读多写少场景优先考虑 READ COMMITTED 隔离级别,避免不必要的间隙锁。
- 把非 DB 操作(如 http 调用、文件处理)移出事务块
- 写操作尽量按主键更新,避免全表扫描更新引发大范围锁
- 批量插入用 INSERT … VALUES (…), (…), (…) 代替 循环 单条插入
- 必要时用 select … for UPDATE 加锁,但必须确保 WHERE 条件走索引,否则会锁整张表
精简查询,别让数据库干多余的事
查 1000 行只用前 10 条?别用 SELECT * FROM table ORDER BY id DESC LIMIT 1000 再在代码里截取——数据库已经做了 990 次无用排序和传输。分页也别无脑用 OFFSET,数据量大时性能断崖式下降。
- 只查需要的字段,避免 SELECT *,尤其别带大文本(TEXT/BLOB)字段
- 分页改用游标方式:记录上一页最后 ID,下一页查 WHERE id
- 复杂统计类查询(如多表 JOIN+GROUP BY+ 聚合)拆出来 异步 更新到汇总表,接口 直接查轻量结果
- 用 union ALL 替代 UNION(除非真需要去重),少一次去重排序开销
适当引入缓存与读写分离
缓存不是万能解药,但对读远大于写的场景非常有效。关键是缓存什么、怎么失效、谁来维护。读写分离则要警惕主从延迟导致的“刚写完就读不到”问题。
- 缓存 热点 数据(如配置表、用户基本信息),设置合理过期时间 + 主动刷新机制
- 写操作后主动删缓存,而不是等自然过期;避免先删缓存再更新 DB 的“双写不一致”风险
- 读写分离时,强一致性读走主库(如订单提交后立刻查详情),普通列表页可走从库
- 不要把所有查询都扔给从库——从库负载过高一样会拖慢主从同步
基本上就这些。高并发 sql 优化 没有银弹,核心是“看清执行路径、控制资源争用、减少无效计算”。每次改 SQL 前,先问自己:这条语句真的需要这么写吗?它在高峰期会扫多少行?锁多久?返回的数据是不是都被用上了?想清楚这几点,效率提升就自然来了。