DP-300 Azure 資料庫管理員 - 第四天課程筆記
CPU 使用率 100%。老闆說加硬體。加了,還是 100%。
講師上課分享了這個真實案例。客戶砸錢升級 CPU,問題紋風不動。最後去查應用程式碼,發現有一段邏輯接近死循環。問題從來不在硬體,是應用層的 Bug 把 CPU 吃死了。
第四天的核心就一句話:性能問題的第一責任人是開發者,不是 DBA。 但偏偏每次系統一慢,所有人第一個找的就是 DBA。所以這天整堂課都在講——怎麼用數據證明問題不在你這裡,以及如果真的在你這裡,該怎麼修。
基準線:你得先知道「正常」長什麼樣子
想像你每天量體溫。37°C 是正常值,如果某天突然飆到 39°C,你知道出問題了。但如果你從來不量,39°C 來的時候你連「異常」都無法判斷。
資料庫的性能基準線就是這個體溫計。要追蹤的關鍵指標有幾個:
緩衝區命中率是記憶體夠不夠用的直接指標。超過 95% 代表記憶體充足,如果一直維持在很高的數字,甚至可以考慮降規格省錢。低於 90%,性能就會明顯掉下去。
磁碟佇列長度不是看讀寫速度,而是看排隊的人有多長。機械硬碟 2-3 是合理值,SSD 可以到 100+ 都還正常——因為 SSD 處理速度夠快,排隊再長也消化得了。這就像高速公路收費站,ETC 車道排 50 台車不算塞,人工車道排 5 台就塞爆了。
還有一點容易踩坑:SQL Server 的記憶體行為像貪吃蛇,預設會佔滿所有可用記憶體。不手動設定 Max Server Memory,作業系統都會被擠到喘不過氣。建議是預留 2-4 GB 給 OS,剩下的都給 SQL Server(專用伺服器的情況)。
Extended Events:指標都正常,但就是慢
最詭異的場景:CPU 正常、記憶體正常、磁碟正常,使用者還是抱怨很慢。
這種時候問題八成藏在鎖和阻塞裡面。兩筆交易互卡,或者有人開了一個超長的 transaction 不放手,其他查詢全部卡在後面排隊。這些在系統層面的監控完全看不到,因為硬體根本沒壓力——壓力全在邏輯層。
Extended Events 就是專門對付這種情況的工具。它取代了舊版的 SQL Profiler,直接內建在引擎裡,輕量到幾乎不影響性能,雲端也完整支援。但重要的是:平常不要開著它。它的定位是「遇到問題才啟動的手電筒」,不是「全天候開著的監視器」。
存儲選擇:不同的活交給不同的工人
選存儲就像選工人。搬磚要找力氣大的,繡花要找手巧的,不能搞反。
Managed Disk 是力氣型——IOPS 高,適合放資料檔案和日誌,需要快速讀寫的場景。Blob Storage 是載貨型——吞吐量大,適合備份,一次搬大量資料。File Storage 是協調型——拿來做叢集仲裁(Quorum/Witness),不需要多快,但要穩。
RAID 配置也有硬規則。本地環境生產用 RAID 10,別碰 RAID 5——講師原話是「看 DBA 用什麼 RAID,就知道專不專業」。雲端就不一樣了,底層已經三副本保護,做個軟體 Striping(等同 RAID 0)就好,容量和性能直接翻倍,磁碟數建議不超過 8 個。
TempDB 的原則只有一條:放在最快的磁碟上。重啟就清空的資料,不需要保護,只需要速度。
SARGability:結果對不代表寫得好
這個觀念可能是整天最值錢的。你寫了一句 SQL,跑出來結果完全正確,但性能慢到爆——因為引擎無法利用索引,被迫全表掃描。
SARG 是 Search ARGument 的縮寫。規則其實很直覺:WHERE 左邊不要放函數。
1 | -- ❌ Non-SARGable(左側有函數,索引直接報廢) |
拿字典舉例最好懂。字典按字母排序,你要找 “apple” 可以直接翻到 A 開頭的地方。但如果你要找「第三個字母是 p 的所有單字」,字典排序幫不了你,只能從頭到尾每個字都看一遍。WHERE 左邊放函數就是在做後面這件事。
索引設計:讀快寫慢的永恆拉扯
碎片低於 5% 不用管,5-30% 用 Reorganize 整理,超過 30% 直接 Rebuild。SSD 上碎片的影響比機械硬碟小很多,所以不用太焦慮,週或月做一次維護就好。
索引維護完記得更新統計資訊。順序不能反過來——統計資訊是查詢最佳化器的地圖,過時的地圖會帶引擎走錯路。
講師分享了一個接案心法,第一句話必問:「這個應用能不能改?」能改,操作空間大,效果好。不能改,DBA 只能在有限範圍內加索引,有時候效果就是有限。這句話背後的意思是——如果需要加一大堆索引才能解決性能問題,真正該改的不是資料庫,是應用架構。
隔離級別:先求正確,再求快
有個經典翻車案例:一張演唱會門票被賣給了兩個人。
原因是用了 READ UNCOMMITTED 隔離級別。兩筆並行交易同時讀到這張票「可售」,然後各自完成購買。性能是很好啦,但業務邏輯炸了。
隔離級別就是在正確性和速度之間選位置。READ UNCOMMITTED 最快但最危險(髒讀);SERIALIZABLE 最安全但可能嚴重阻塞;SNAPSHOT 用 TempDB 空間換取不阻塞的讀取,但有版本衝突的風險。沒有完美選項,只有適合你業務場景的選項。
死鎖(Deadlock)用 Extended Events 抓。但有一種更隱蔽的東西叫 Spinlock(物理鎖),發生在 CPU 層面,所有監控指標都顯示正常,系統就是慢。排查方向是先看 CPU 有沒有開超線程或超分配——資料庫的 VM 最好別用這兩個功能。
自動調優:讓引擎自己學
Query Store 是 SQL Server 2016 之後最實用的功能之一。它幫你保存執行計畫的歷史版本(比如最近 15 個版本),引擎會自動比較哪個版本最快,如果新的版本反而退步了,它能自動回退到舊版。
Azure SQL Database 預設就開著。本地部署需要手動啟用,這步千萬別忘。
有個小陷阱:自動索引管理可能會刪掉某些看起來沒用的索引。但如果應用程式碼裡面用了 Index Hint 指定那個索引名稱,索引一被刪,應用直接報錯。所以上自動索引前,先確認程式碼沒有寫死索引名稱。
最後,查詢提示(Query Hints)的建議是盡量不用。提示等於是你告訴引擎「用這個方法跑」,但開發環境的最佳方法不見得適合生產環境。不寫提示,就是給引擎最大的自由去做最佳化。講師的比喻很精準:「你導航都設好了,還一直跟司機說左轉右轉,不如讓他自己開。」
第四天的資訊量很大,但背後的思路其實就兩條線——怎麼找到問題(監控、Extended Events、執行計畫),以及怎麼避免問題(SARGability、索引策略、隔離級別選擇)。抓住這兩條線,細節自然能串起來。









