首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

一條 SELECT * 釀成災難:從網絡 IO 爆滿到系統癱瘓的排查實戰

     編輯:關於SqlServer

事件還原:上線第二天系統「癱瘓」

某專案剛上線第二天,後台監控發現異常:資料庫服務器與 IIS 服務器之間的網絡 IO 直接衝上 70%–100%(1 Gbps 頻寬被佔滿,每秒傳輸 700 MB–1 GB),資料庫記憶體飆升至 21 GB,IIS CPU 長期維持在 80%–90%,導致網站頻繁出現連線逾時。團隊被迫緊急關站維護,展開全方位排查。

兇手鎖定:一條看似無害的 SELECT *

經過一小時的日誌分析與蹤跡,鎖定問題核心——一條語法完全正確的 SQL:

SELECT * FROM Table1

為何會釀禍?

  • 數據量大:Table1 存放 10 萬+ 行,每日新增上萬行。
  • 調用頻率極高:為了統計總行數,前端每秒調用不低於 1,000 次。
  • 全表掃描 + 全量傳輸:每次查詢都會把 10 萬行所有欄位的數據從資料庫傳到應用層,再由應用層在記憶體中計數,造成網絡、記憶體、CPU 三重壓力。

一鍵止血:改寫為 COUNT(*)

SELECT COUNT(*) FROM Table1

修改上線後,網絡 IO 瞬間跌至 10 MB 以下,資料庫記憶體穩定在預期的 12 GB,CPU 占用大幅下降,系統恢復正常。

深度複盤:為何耗時 6 小時?

階段耗時關鍵動作
問題發現與定位1 小時監控告警 → 關站 → 開啟 Profiler / Extended Events → 鎖定高頻 SQL
代碼變更與驗證5 小時跨多個微服務搜尋調用點 → 修改 ORM / 存儲過程 → 回歸測試 → 灰度發布

教訓:「簡單」的 SQL 最容易被忽視。上線前的效能基準測試、索引審查、以及「統計類查詢禁止 SELECT *」的編碼規範,能將此類風險壓縮到分鐘級。

最佳實踐清單

  1. 統計行數務必用 COUNT(*) 或觸發器維護計數表。
  2. 避免在高頻介面使用 SELECT *;只取必要欄位。
  3. 為大表建立覆蓋索引,讓 COUNT(*) 僅掃描索引頁。
  4. 引入 APM(如 SkyWalking、Pinpoint)自動捕捉高頻慢 SQL。
  5. 建立「SQL 變更審核機制」,任何上線腳本需經 DBA 過目。

看似微小的語句優化,實則是系統穩定性的分水嶺。下次再見 SELECT *,請三思而後行。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved