SQL Server 查詢優化 22 條黃金法則:從索引到架構
查詢緩慢十大根因
- 無索引或索引未命中(最常見)
- I/O 吞吐瓶頸
- 缺乏計算欄位導致掃描
- 記憶體不足
- 網路延遲
- 回傳資料量過大
- 鎖/死鎖競爭
- 不必要的行/列回傳
- SQL 寫法不佳
- 統計資訊過舊
架構與硬體層優化
- 檔案分離:資料、記錄、索引、Tempdb 放不同磁碟/RAID 群,提升平行 I/O。
- 資料表分割:水平分割(範圍/雜湊)、垂直分割(熱冷欄位分離),
sp_spaceuse 監控大小。
- 升級硬體:SSD、更多記憶體、多核心 CPU。
- 記憶體配置:
max server memory 設實體 80-90%,AWE (32-bit) 或直接 64-bit 版本。
- 並行度:
MAXDOP 視核心數設定,複雜查詢受益,OLTP 小查詢設 1。
索引設計原則
- 依
WHERE、JOIN、ORDER BY 欄位建立索引,填充因子預設 (0) 通常最佳。
- 索引鍵越窄越好(
INT 優於 VARCHAR(50)),避免低選擇性欄位(如性別)建單欄索引。
- 單查詢最多用一個索引(舊版限制),新版可
INDEX INTERSECTION。
- 覆蓋索引消除 Key Lookup:
INCLUDE 非鍵欄位。
- 定期
DBCC INDEXDEFRAG/REBUILD 消除碎片,UPDATE STATISTICS 刷新統計。
T-SQL 寫法優化 22 條
- WHERE 子句限制回傳行,避免全表掃描鎖表。
- 避免游標,改用集合操作、臨時表、Table Variable、CTE、
CASE 表達式。
- 游標並發選項:
READ_ONLY、OPTIMISTIC、SCROLL_LOCKS 依業務選擇。
- 用 Profiler/Extended Events 追蹤 慢查詢,配合
Database Engine Tuning Advisor 建議索引。
- UNION ALL 優於 UNION(無去重開銷)。
- 慎用 DISTINCT,同樣觸發排序/雜湊去重。
- 不回傳不需要的行/列,減少網路與序列化成本。
- SET QUERY_GOVERNOR_COST_LIMIT 或 Resource Governor 限制資源濫用。
- TOP / SET ROWCOUNT 限制影響範圍。
- 避免 WHERE 中對欄位用函數(
CONVERT、SUBSTRING),改用計算欄位+索引或改寫 LIKE 'm%'。
- 負向條件不走索引:
IS NULL、<>、NOT IN、NOT EXISTS、NOT LIKE、LIKE '%xxx' → 改用 EXISTS、LEFT JOIN ... IS NULL。
- COMMIT/ROLLBACK 包裹動態 SQL 時放外層,避免隱性交易。
- SQL 註解不影響執行計畫,放心撰寫。
- 頁面結構:8KB 頁、64KB 區、B+Tree 儲存,理解有助於設計填充因子。
- 分散式分區檢視:水平分割 + 同名檢視實現 Scale-out。
- OLTP/OLAP 分離:讀寫分離、唯讀副本、資料倉庫。
- 全文索引:
LIKE '%keyword%' 改用 Full-Text Search,節省空間用 VARCHAR 非 CHAR。
- 動態 SQL 參數化:
sp_executesql 重用計畫,防注入。
- 避免隱含轉換:
WHERE varchar_col = 123 導致索引失效,統一資料類型。
- 批次處理大量 DML:分批
TOP (5000) 循環,避免長交易鎖升級。
- 監控
sys.dm_exec_query_stats 找出高 CPU/IO/持續時間查詢。
- 定期清理計畫快取:
DBCC FREEPROCCACHE (謹慎) 或針對性 sp_recompile。
copyright ©
萬盛學電腦網 all rights reserved