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

来源:这里教程网 时间:2026-02-28 20:36:52 作者:

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

这是并发查询变慢最常见原因。当多个请求同时执行

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
可避免间隙锁(但需评估一致性风险)
尽量用等值查询代替范围条件;若必须范围查询,考虑加覆盖索引减少锁粒度

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-python 的
pool_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。

相关推荐