mysql并发查询慢是什么原因_mysql性能瓶颈分析

7次阅读

并发查询变慢主因是锁、缓存、连接三者叠加:未走索引致全表扫描;间隙锁阻塞;buffer pool 不足引发频繁刷脏页;连接数打满或线程竞争严重。

mysql 并发查询慢是什么原因_mysql 性能瓶颈分析

查询没走索引导致全表扫描

这是并发查询变慢最常见原因。当多个请求同时执行 SELECT 且 WHERE 条件列没建索引,MySQL 就得反复读取整张表,磁盘 I/O 暴涨,CPU 和 buffer pool 压力陡增。

  • EXPLAIN 检查执行计划,重点关注 type 是否为 ALLindexkey 是否为 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 可避免间隙锁(但需评估一致性风险)
  • 尽量用等值查询代替范围条件;若必须范围查询,考虑加覆盖索引减少锁粒度

buffer pool 不足 + 频繁刷脏页

并发查询多时,若 innodb_buffer_pool_size 设置过小(比如默认 128MB),会导致大量数据页频繁进出内存,同时后台线程拼命刷脏页(innodb_io_capacity 不够也会拖慢)。

  • 监控 SHOW ENGINE INNODB STATUS 中的 Buffer pool hit rate,低于 95% 就该扩容
  • 生产环境建议设为物理内存的 50%–75%,但不要超过 80%
  • 检查 innodb_log_file_size 是否太小——日志频繁切换会强制刷脏页,放大 I/O 压力

连接数打满或线程竞争严重

并发请求 数超过 max_connections,新连接会被拒绝或排队;即使没超限,线程创建 / 销毁开销、锁竞争(如 LOCK_thread_count)也会让查询响应时间抖动增大。

  • SHOW STATUS LIKE 'Threads_connected''Threads_running' 对比实时连接负载
  • 应用层务必启用连接池(如 HikariCP、mysql-connector-pythonpool_size),避免短连接风暴
  • 避免在事务里做 HTTP 调用、文件读写等耗时操作,否则连接被长期占用,实际并发能力远低于配置值
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。

text=ZqhQzanResources