并发查询变慢主因是锁、缓存、连接三者叠加:未走索引致全表扫描;间隙锁阻塞;buffer pool不足引发频繁刷脏页;连接数打满或线程竞争严重。
这是并发查询变慢最常见原因。当多个请求同时执行 SELECT 且 WHERE 条件列没建索引,MySQL 就得反复读取整张表,磁盘 I/O 暴涨,CPU 和 buffer pool 压力陡增。
EXPLAIN 检查执行计划,重点关注 type 是否为 ALL 或 index,key 是否为 NULL
(a, b, c),WHERE b = ? 仍不会命中VARCHAR 但传入数字参数:WHERE user_id = 123(而 user_id 实际是字符串)InnoDB 在可重复读隔离级别下,范围查询(如 WHERE status IN (1,2))可能触发间隙锁(Gap Lock),导致多个事务互相等待,看起来像“查询卡住”。
SELECT * FROM information_schema.INNODB_TRX 查当前活跃事务,结合 INNODB_LOCK_WAITS 看谁在等谁READ COMMITTED 可避免间隙锁(但需评估一致性风险)并发查询多时,若 innodb_buffer_pool_size 设置过小(比如默认 128MB),会导致大量数据页频繁进出内存,同时后台线程拼命刷脏页(innodb_io_capacity 不够也会拖慢)。
SHOW ENGINE INNODB STATUS 中的 Buffer pool hit rate,低于 95% 就该扩容innodb_log_file_size 是否太小——日志频繁切换会强制刷脏页,放大 I/O 压力当并发请求数超过 max_connections,新连接会被拒绝或排队;即使没超限,线程创建/销毁开销、锁竞争(如 LOCK_thread_count)也会让查询响应时间抖动增大。
SHOW STATUS LIKE 'Threads_connected' 和 'Threads_running' 对比实时连接负载pool_size),避免短连接风暴SELECT trx_id, trx_state, trx_started, trx_wait_started, trx_mysql_thread_id, trx_query FROM information_schema.INNODB_TRX WHERE trx_state = 'LOCK WAIT';
真正卡住的往往不是 SQL 写得差,而是锁、缓存、连接三者叠加作用的结果。调优时别只盯着单条语句的执行时间,先看 Threads_running 是否持续高位,再查锁等待,最后才优化 SQL。