第四天講完才懂,性能問題根本不是 DBA 的責任啦,是開發者的鍋。但偏偏所有人都先來找我們。

性能監控的真相

某個客戶 CPU 爆到 90-100%,業務部門說「快加硬體啦」。結果加了新 CPU 以後,還是一樣爆。講師跑過去一看,才發現應用層有個死循環 Bug,天啊。所以第一個功課就是別盲目加硬體,先找出瓶頸在哪。

性能基準線要分兩個角度看:終端使用者看頁面載入 3-5 秒是否夠快,資料庫後端看 CPU 使用率、緩衝區命中率(要 >95%)、磁碟佇列長度、TPS。記憶體這塊要特別注意,SQL Server 會像貪吃蛇一樣把所有記憶體吃光,必須手動設定 Max Server Memory。但這也給了我們省錢的角度,緩衝區命中率達到 95% 就代表記憶體夠了,說不定可以降規格。

找問題的工具

Extended Events 徹底取代了舊版 SQL Profiler,輕量、內建在引擎,雲端也支援。關鍵場景是 CPU/記憶體/磁碟看起來都很正常,但查詢就是慢,那就可能躲著鎖或阻塞。平常千萬別開著它,會整天記錄資料,遇到問題才啟動找原因。

執行計畫從右到左讀,越貴的運算子在前面,往往就是那個地方爆了。DMV 也很好用,sys.dm_* 可以查連線數、來源 IP,找到誰在打爆伺服器。

儲存和磁碟配置

本地環境生產必用 RAID 10,別碰 RAID 5(這是判斷 DBA 專不專業的指標啦)。雲端底層已經三副本了,其實做軟體 Striping(RAID 0)就夠,磁碟最多 8 個。TempDB 要放在最快的磁碟,因為它 I/O 最兇悍。

選存儲類型也有眉角:Managed Disk 給資料檔案(高 IOPS)、Blob Storage 給備份(高吞吐量)、File Storage 給叢集仲裁。

SARGability:不要害自己

WHERE 左側放函數就完蛋了。YEAR(OrderDate) = 2026 是 Non-SARGable,改成 OrderDate >= '2026-01-01' AND OrderDate < '2027-01-01' 才行。前置 % 的 LIKE 也一樣,'%keyword' 不行,搜尋引擎沒辦法用索引。

真香的地方是,結果正確不代表性能沒問題。SQL 會幫你算對答案,但慢到爆。這點踩坑過才懂。

1
2
3
4
5
6
-- Non-SARGable (炸了)
SELECT * FROM Orders WHERE YEAR(OrderDate) = 2026;

-- SARGable (真香)
SELECT * FROM Orders
WHERE OrderDate >= '2026-01-01' AND OrderDate < '2027-01-01';

索引和統計

索引碎片<5% 不處理,5-30% Reorganize,>30% Rebuild。SSD 上碎片影響比較小,但傳統硬碟很致命。統計資訊更新要在索引維護以後,順序很重要。

讀快寫慢,這個權衡永遠存在。如果只是少量索引能提升性能,放心加。但需要加一堆索引才解決問題,那就得反思應用設計是不是有問題。講師說他接案第一句就問「應用能不能改?」,太中肯了。

隔離級別和死鎖

業務正確性永遠優先於性能。曾經有個案例,一張票被賣給兩個人,因為用了 READ UNCOMMITTED。五個隔離級別從 READ UNCOMMITTED 一路到 SERIALIZABLE 加 SNAPSHOT。選擇的時候要想清楚。

死鎖找 Extended Events,物理鎖(Spinlock)更鬼,CPU 層面的東西,DMV 監控看不到,表現就是一切正常但就是慢。

Query Store 和自動調優

SQL Server 2016 以後有 Query Store,保存執行計畫歷史,會自動選最優的版本。Azure SQL 預設啟用,本地需手動開。自動索引管理有時會和 Index Hints 起衝突,要注意。

日常維護

生產環境用完整恢復模式,搭配定期日誌備份。Resource Governor 可以限制個別 DB 的 CPU/記憶體/IOPS,但別傻傻地用容器部署生產資料庫,容器是 OS 層資源控制,引擎感受不到。

規範化 vs 反規範化,OLTP 用規範化,OLAP 用反規範化。別拿 OLTP 理論去設計資料倉庫,不同思維方式。

查詢提示通常不要用,讓引擎自動決定最好,提示只會限制優化空間。


第四天的內容滿坑滿谷,最深的感覺就是性能問題看似簡單,其實需要很多細節累積。下一天應該要進 Azure 雲端部分的內容,敬請期待。