基於多年實戰教訓總結的 21 條 SQL Server 開發鐵律,涵蓋工具掌握、游標禁忌、範式堅持、索引策略、事務並發、大數據操作、編碼規範等核心領域。遵循這些原則,可避開 90% 的效能坑與邏輯坑。
- 精通工具箱:花一個週末瀏覽所有 T-SQL 命令與 SSMS 功能,遇到問題時能想起「有個命令能解決」,再查語法。
- 拒絕游標:游標 = 循環執行 SELECT,10000 行 = 10000 次 SELECT。改用集合操作(JOIN/APPLY/窗口函數),效能提升百倍。實戰:游標存儲過程 40 分鐘 → 集合寫法 10 秒。
- 堅持範式化:窄表、多表、少冗餘。反範式化多為懶惰或錯誤優化,DBMS 優化器最擅長處理範式化模型。
- 禁止
SELECT *:指定列 → 減少 I/O、啟用覆蓋索引、防 schema 變更導致應用報錯。
- 知曉數據操作畫像:索引加速讀、拖慢寫。根據「讀多寫少/寫多讀少」決策索引數量與類型。
- 低選擇性列不建索引:如「性別」僅分兩半,掃描 50% 數據不如全表掃描。組合索引前導列按選擇性遞減排序(姓名 > 省份 > 性別)。
- 長事務用顯式事務:
BEGIN TRAN ... COMMIT/ROLLBACK,防止中途失敗留下髒數據,減少鎖持有時間。
- 統一鎖表順序防死鎖:所有存儲過程按固定順序訪問表(如 A→B),打破「請求與等待」循環條件。
- 拒絕大結果集直推前端:ComboBox 載入 10 萬行 = 用戶詛咒。分頁、搜索、虛擬滾動,單頁 ≤ 200 行。
- 優先客戶端游標:減輕服務器內存/鎖壓力,縮短鎖持有時間。
- 強制參數化查詢:
Command + Parameters 替代字符串拼接,復用執行計畫,防注入,避免單引號轉義地獄。
- 開發環境用真實數據量:硬盤便宜,效能問題早發現早解決。生產級數據量測試才能暴露掃描、鎖升級、Tempdb 爭用。
- 大批量導入用 BCP/BULK INSERT:
INSERT 逐行記錄日誌、觸發器、索引維護;最小日誌模式下 BCP 速度快 10-100 倍。
- 關注超時設置:默認 15-30 秒,長查詢需在連接字符串/命令對象顯式設定
CommandTimeout。
- 樂觀並發控制:表加
ROWVERSION/TIMESTAMP 列,更新前比對,衝突則提示用戶刷新重試。
- 新增主鍵值用
SCOPE_IDENTITY():@@IDENTITY 受觸發器干擾,IDENT_CURRENT 受併發干擾,SCOPE_IDENTITY 最安全。
- 慎用 NULLable 列:每行額外 1 字節位圖開銷,查詢需
IS NULL 判斷,碼表/關聯鍵建議 NOT NULL DEFAULT ''。
- 避開 TEXT/NTEXT/IMAGE:舊 LOB 類型查詢慢、不可索引、易產生碎片。改用
VARCHAR(MAX)/NVARCHAR(MAX)/VARBINARY(MAX)。
- 少用臨時表:優先用 CTE/子查詢/表變量(
@table TABLE(...))。臨時表在連接池環境下生命週期不可控,易殘留。
- 善用執行計畫分析:SSMS
Ctrl+M 顯示實際計畫,關注 Estimated vs Actual Rows、Missing Index、Spill Warning、Parallelism。
- 啟用參考完整性:PK、FK、Unique、Check 約束下推至引擎層,比應用層檢查快數量級,且保證數據一致性。
附錄:快速自檢清單
- [ ] 所有表有 PK?聚集索引鍵窄/穩定/遞增?
- [ ] 非聚集索引 ≤ 5 個/表?前導列高選擇性?覆蓋高頻查詢?
- [ ] 存儲過程無游標?動態 SQL 參數化?
- [ ] 事務最小範圍?鎖順序統一?
- [ ] 大批量操作用 BULK INSERT/BCP?
- [ ] 開發庫數據量 ≥ 生產 10%?
- [ ] 連接字符串設 CommandTimeout?
- [ ] 錯誤處理統一 TRY/CATCH + 記錄?