核心觀點
經驗證明,SQL Server 效能提升主要取決於三大面向:**邏輯資料庫設計、索引設計、查詢設計**。最大的效能問題亦源於此三者缺陷。硬體資源 (記憶體、CPU、磁碟) 固然重要,但 SQL Server 具備自動管理機制,投資回報率遠低於上述三面向的調整。
一、邏輯資料庫設計
- 正規化:消除資料冗余,減少更新異常,縮小資料列寬度 → 更多列放入一頁 → 讀取更少頁面。
- 資料類型選擇:優先用 `INT` 而非 `BIGINT`、`VARCHAR(n)` 而非 `CHAR(n)`、`DATE` 而非 `DATETIME` (若不需時間)。避免 `MAX` 類型除非必要。
- 主鍵設計:窄、唯一、不變、遞增 (Identity) → 叢集索引碎片最少、非叢集索引鍵值最小。
二、索引設計
- 叢集索引:每張表最多一個,決定資料物理順序。預設建在 PK,但若 PK 為 GUID 或複合鍵,考慮改用 Surrogate Key (Identity) 為叢集鍵,PK 改為非叢集唯一索引。
- 非叢集索引:覆蓋查詢常用的 WHERE、JOIN、ORDER BY、GROUP BY 欄位。使用 `INCLUDE` 列覆蓋 SELECT 列,避免 Key Lookup。
- 維護:定期 `ALTER INDEX ... REORGANIZE/REBUILD` 並 `UPDATE STATISTICS`,保持統計資料準確。
三、查詢設計
- 避免 SELECT *:只取需要欄位,利用覆蓋索引,減少 I/O 與網路傳輸。
- SARGable 條件:`WHERE col = @param` 而非 `WHERE FUNCTION(col) = @param`,讓優化器能用索引 Seek。
- 參數化查詢:使用 `sp_executesql` 或參數化命令,重用執行計畫,防止 SQL 注入。
- 分頁查詢:SQL Server 2012+ 使用 `OFFSET ... FETCH`,舊版用 `ROW_NUMBER()` CTE。
- 避免游標/迴圈:集合式操作 (JOIN、EXISTS、窗口函數) 效能遠優於逐列處理。
系統層面微調 (次要)
- Max Server Memory:保留 4-8 GB 給 OS,避免記憶體壓力導致分頁。
- TempDB 多檔案:依邏輯 CPU 核心數建立等量資料檔 (最多 8),減少 PFS/GAM/SGAM 爭用。
- Instant File Initialization:授權服務帳號 `Perform Volume Maintenance Tasks`,加速資料檔擴充。
優化流程建議
- 識別高耗資源查詢 (Query Store、DMV `sys.dm_exec_query_stats`)。
- 分析執行計畫 (實際 vs 估計、缺失索引提示)。
- 優先修正查詢與索引,驗證改善。
- 再檢視結構設計是否需調整 (正規化/反正規化權衡)。
- 最後才考慮硬體升級。