站点訪問變慢时,很多人第一反應是加带宽、換服務器,或者检查前端资源。但真正到了流量高峰,先撑不住的往往是資料库。连接數被占满、慢查询堆积、鎖等待變長,都會让頁面請求排队,最後表現為“整站都在轉圈”。這篇文章整理一份資料库层面的自查思路,适合站点运营、运维和開發一起對照使用。
為什么高峰期更容易暴露資料库問题
平时訪問量小,單條查询用了几百毫秒也不明顯;一旦並發上来,同样的查询會反复执行,資料库连接很快被占满。新的請求拿不到连接,就只能等待或直接报错。更麻烦的是,慢查询會拖住其他查询,形成连鎖反應。
頁面變慢不一定等于服務器不够强,先看資料库是否已经在超负荷工作。
连接數自查
最大连接數與實际占用
查看資料库目前连接數和最大连接數,確認两者之間的余量。如果高峰时段经常接近上限,就要分析是连接没有及时释放,還是並發确實超過了承载能力。
- 观察连接數在一天中的峰值,而不是只看平均值。
- 確認應用是否使用了连接池,连接池大小是否和資料库上限匹配。
- 检查是否有连接泄漏,例如請求結束後没有归還连接。
- 避免多個服務各自設定過大的连接池,把資料库当成無限资源。
连接超时與排队
连接超时設定過短,高峰期容易直接失敗;設定過長,請求會一直排队,訪客看到的就是長時間無响應。需要结合业務容忍度,設定合理的连接超时、讀取超时和重试策略。
慢查询自查
慢查询日誌是定位問题的起点。不要只看“最慢的那一條”,還要看“执行次數最多的那一條”。一條 200 毫秒的查询,如果每分钟执行几千次,消耗的资源可能比偶尔出現的几秒查询更大。
- 開啟慢查询日誌,設定一個合理的阈值,例如 200 毫秒到 500 毫秒。
- 按执行次數、總耗时、平均耗时分別排序,找出真正的大头。
- 關注没有使用索引、掃描行數很大的查询。
- 检查是否在循环里逐條查询,能合並的尽量合並。
索引是否被用上
建了索引不等于查询會走索引。字段類型不一致、在索引列上做函數运算、前導通配符模糊匹配,都可能让索引失效。自查时可以查看执行計划,確認關键查询的訪問方式。
- 经常出現在 WHERE、ORDER BY、JOIN 中的字段,考虑是否需要索引。
- 联合索引注意字段顺序,把区分度高的字段放在前面。
- 避免重复索引和冗余索引,它們會增加寫入负担。
- 索引不是越多越好,每次新增都要评估對寫入和存储的影响。
查询寫法與缓存
有些問题不用改架构,調整查询就能缓解。例如只取需要的字段、限制返回條數、避免一次性拉取大量資料、把复杂統計改成异步任務。對于讀多寫少且變化不频繁的資料,可以考虑加一层缓存,但要注意缓存失效和一致性。
分頁查询的坑
深度分頁在資料量大时很容易變慢。翻到很後面的頁碼时,資料库可能仍然需要掃描大量行。可以尝试基于游标的分頁,或者限制可訪問的最大頁碼,避免無意义的深度翻頁消耗资源。
批量操作與鎖等待
批量更新、批量刪除如果一次影响太多行,可能長時間持有鎖,阻塞其他查询。建议拆成小批次执行,並在低峰期執行。同时關注鎖等待和死鎖日誌,找到相互阻塞的语句。
日常巡检與告警
資料库問题最好在爆發前被發現。可以設定连接數、慢查询數量、鎖等待時間、磁盘空間等指标的告警阈值,並在流量上涨前做一次压测或检查。
- 每日查看慢查询趋势,而不是等到頁面打不開才查。
- 记錄資料库版本、參數配置和最近變更,方便對比。
- 變更前备份,變更後观察连接數、慢查询和错誤日誌。
- 把資料库巡检纳入站点运营的例行清單,明确负责人。
處理顺序建议
遇到高峰期變慢,可以先確認连接數是否接近上限,再查目前正在执行的慢查询,然後看是否有鎖等待。临时缓解可以限流、重啟连接池或临时關閉非核心統計任務;但根本解决還是要回到查询優化、索引調整和容量規划。
資料库自查不需要一次做完,可以從最影响頁面打開速度的几個查询開始。把观察、優化、驗證變成固定動作,站点在流量波動时會更稳一些。