站点访问变慢时,很多人第一反应是加带宽、换服务器,或者检查前端资源。但真正到了流量高峰,先撑不住的往往是数据库。连接数被占满、慢查询堆积、锁等待变长,都会让页面请求排队,最后表现为“整站都在转圈”。这篇文章整理一份数据库层面的自查思路,适合站点运营、运维和开发一起对照使用。
为什么高峰期更容易暴露数据库问题
平时访问量小,单条查询用了几百毫秒也不明显;一旦并发上来,同样的查询会反复执行,数据库连接很快被占满。新的请求拿不到连接,就只能等待或直接报错。更麻烦的是,慢查询会拖住其他查询,形成连锁反应。
页面变慢不一定等于服务器不够强,先看数据库是否已经在超负荷工作。
连接数自查
最大连接数与实际占用
查看数据库当前连接数和最大连接数,确认两者之间的余量。如果高峰时段经常接近上限,就要分析是连接没有及时释放,还是并发确实超过了承载能力。
- 观察连接数在一天中的峰值,而不是只看平均值。
- 确认应用是否使用了连接池,连接池大小是否和数据库上限匹配。
- 检查是否有连接泄漏,例如请求结束后没有归还连接。
- 避免多个服务各自设置过大的连接池,把数据库当成无限资源。
连接超时与排队
连接超时设置过短,高峰期容易直接失败;设置过长,请求会一直排队,访客看到的就是长时间无响应。需要结合业务容忍度,设置合理的连接超时、读取超时和重试策略。
慢查询自查
慢查询日志是定位问题的起点。不要只看“最慢的那一条”,还要看“执行次数最多的那一条”。一条 200 毫秒的查询,如果每分钟执行几千次,消耗的资源可能比偶尔出现的几秒查询更大。
- 开启慢查询日志,设置一个合理的阈值,例如 200 毫秒到 500 毫秒。
- 按执行次数、总耗时、平均耗时分别排序,找出真正的大头。
- 关注没有使用索引、扫描行数很大的查询。
- 检查是否在循环里逐条查询,能合并的尽量合并。
索引是否被用上
建了索引不等于查询会走索引。字段类型不一致、在索引列上做函数运算、前导通配符模糊匹配,都可能让索引失效。自查时可以查看执行计划,确认关键查询的访问方式。
- 经常出现在 WHERE、ORDER BY、JOIN 中的字段,考虑是否需要索引。
- 联合索引注意字段顺序,把区分度高的字段放在前面。
- 避免重复索引和冗余索引,它们会增加写入负担。
- 索引不是越多越好,每次新增都要评估对写入和存储的影响。
查询写法与缓存
有些问题不用改架构,调整查询就能缓解。例如只取需要的字段、限制返回条数、避免一次性拉取大量数据、把复杂统计改成异步任务。对于读多写少且变化不频繁的数据,可以考虑加一层缓存,但要注意缓存失效和一致性。
分页查询的坑
深度分页在数据量大时很容易变慢。翻到很后面的页码时,数据库可能仍然需要扫描大量行。可以尝试基于游标的分页,或者限制可访问的最大页码,避免无意义的深度翻页消耗资源。
批量操作与锁等待
批量更新、批量删除如果一次影响太多行,可能长时间持有锁,阻塞其他查询。建议拆成小批次执行,并在低峰期运行。同时关注锁等待和死锁日志,找到相互阻塞的语句。
日常巡检与告警
数据库问题最好在爆发前被发现。可以设置连接数、慢查询数量、锁等待时间、磁盘空间等指标的告警阈值,并在流量上涨前做一次压测或检查。
- 每日查看慢查询趋势,而不是等到页面打不开才查。
- 记录数据库版本、参数配置和最近变更,方便对比。
- 变更前备份,变更后观察连接数、慢查询和错误日志。
- 把数据库巡检纳入站点运营的例行清单,明确负责人。
处理顺序建议
遇到高峰期变慢,可以先确认连接数是否接近上限,再查当前正在执行的慢查询,然后看是否有锁等待。临时缓解可以限流、重启连接池或临时关闭非核心统计任务;但根本解决还是要回到查询优化、索引调整和容量规划。
数据库自查不需要一次做完,可以从最影响页面打开速度的几个查询开始。把观察、优化、验证变成固定动作,站点在流量波动时会更稳一些。