MySQL存储过程不支持多线程,WHILE循环在单会话中串行执行,易引发锁争用、日志刷写和CPU瓶颈;真正提升吞吐需批量操作、小事务拆分与异步解耦,而非依赖存储过程内部并发。不靠谱——存储过程本身不支持多线程,所谓“多线程并发调用存储过程”,实际是多个客户端线程各自发起独立的数据库连接和事务,彼此之间没有协同、不共享状态、也不自动并行化内部逻辑。真正要命的是:很多人误以为把循环塞进存储过程里(比如用
WHILE 逐行处理),就能“并发加速”,结果反而把锁、日志、CPU全堵死在单个会话里。WHILE 循环 ≠ 并发存储过程运行在单个数据库会话中,WHILE 是串行执行的。哪怕你循环插入 1000 行,它也是一行接一行地走,每行都可能加锁、刷日志、触发索引维护。
SELECT ... FOR UPDATE 或 UPDATE,锁会持续到整个循环结束(除非手动 COMMIT)WHILE 中调用函数或查表,每次都要重新解析、权限校验、上下文切换,开销远高于批量 SQL多个应用线程同时 CALL proc_deduct_stock(123, 1) 是完全可行的,InnoDB 能按行锁隔离。问题出在过程内部是否“事务太大”“锁太早”“索引缺失”。
START TRANSACTION,中间查库存、扣减、记日志、发消息(伪代码),最后才 COMMIT → 网络延迟或日志写入慢,直接拖住锁SELECT ... FOR UPDATE 紧贴 UPDATE 前,且确保 product_id 有索引 → 锁范围小、时间短存储过程不是并发调度器。压测时发现 TPS 上不去,优先排查的应是锁等待、redo log 刷盘、索引缺失,而不是给存储过程加“并行关键字”(MySQL 根本没有)。
INSERT INTO ... VALUES (), (), () 一次插 100 行,比存储过程里循环 100 次 INSERT 快 5–10 倍INSERT IGNORE 或乐观锁 + 应用层重试,别依赖 SELECT FOR UPDATE 死等SHOW ENGINE INNODB STATUS 里的 lock wait timeout exceeded,再查 performance_schema.events_waits_summary_global_by_event_name 找 mutex 瓶颈