




SQL查询变慢通常不是数据库容量问题,而是慢查询、锁等待、连接数满等表象,根源在于未做读写分离、缺少缓存、索引缺失;应先查进程列表与执行计划,再分层优化读写与连接管理。
不是所有“突发流量”都该由数据库硬扛。多数情况下,慢查询、锁等待、连接数打满才是表象,背后往往是没做读写分离、缺少缓存兜底,或单条 SQL 没走索引。先别急着扩容,查 SHOW PROCESSLIST 看有没有 Locked 或 Sending data 卡住的长事务;用 EXPLAIN 确认关键查询是否走了索引——尤其是 WHERE、JOIN、ORDER BY 字段上有没有复合索引覆盖。
读请求是突发流量中最容易放大的部分,必须隔离:
Redis 缓存 5 分钟,避免每秒几百次打到 SELECT * FROM users WHERE id = ?
LIMIT 强制分页,禁用 OFFSET 大翻页,改用游标式分
WHERE created_at )
SELECT COUNT(*),改用近似值(MySQL 8.0+ 可查 information_schema.INNODB_TABLESTATS)或业务侧维护计数器写入瓶颈往往卡在磁盘 I/O 和事务日志刷盘:
INSERT INTO ... VALUES (...), (...), (...),而不是循环单条 INSERT;每批控制在 500~1000 行,太大反而触发锁升级或内存溢出SET unique_checks=0),导入完成后再开,但仅限离线导入场景ClickHouse 或 TimescaleDB,别硬塞进 MySQLinnodb_log_file_size 是否过小——日志太小会导致频繁刷盘,建议设为 1G~4G(需重启生效)Too many connections 怎么破?这通常是连接泄漏或连接池配置失当:
connect_timeout)、空闲超时(idle_timeout)、最大连接数(max_connections),不能依赖数据库默认值wait_timeout 和 interactive_timeout 前,先确认是不是应用没正确 close Connection 或 ResultSet
KILL 掉状态为 Sleep 且 Time 超过 60 秒的连接,但只是掩耳盗铃,得回溯代码里哪块没释放资源真实压测中,80% 的“扛不住”其实发生在应用没关自动提交、ORM 生成了 N+1 查询、或者前端重试逻辑没加退避——数据库只是把上游的问题放大了而已。