架構分層總覽
應用程式
│
▼
API / 物件庫層 (ODBC, DB-Library, OLE DB, ADO, ADO.NET)
│
▼
Net-Library (網路庫) ──透明傳輸──► 網路協定 (TCP/IP, Named Pipes, Shared Memory, VIA...)
│
▼
SQL Server 伺服器端 (TDS 封包交換)
1. API / 物件庫層:兩大主流體系
OLE DB / ADO (COM 架構)
- 應用程式透過 OLE DB 提供者 (Provider) 與伺服器溝通。最常用:**SQLOLEDB** (Microsoft OLE DB Provider for SQL Server),隨 MDAC 安裝。
- ADO 使用 `Connection` 物件 + 連線字串 (`Provider=SQLOLEDB;...`)。
- ADO 亦可經由 **OLE DB Provider for ODBC** 走 ODBC 路徑 (連線字串含 `DSN=` 或 `Driver=`)。
ADO.NET (Managed 架構) —— 現代首選
- .NET Framework Data Provider for SQL Server** (`SqlClient`):原生 Managed 程式碼,直接用 TDS 協定與 SQL Server 溝通,**效能最佳、功能最全**。核心類別:`SqlConnection`、`SqlCommand`、`SqlDataReader`、`SqlDataAdapter`。
- 亦可透過 `OleDbConnection` 使用 SQLOLEDB,或 `OdbcConnection` 走 ODBC —— 三條路徑擇一,故障排查時可隔離問題層級。
2. Net-Library (網路庫):客戶端透明傳輸層
SQL Server 為各主流協定提供 Net-Library,負責將上層請求封裝為網路封包,反之亦然。可用 用戶端網路工具 (cliconfg.exe) 配置啟用順序與別名。
| Net-Library | 協定 | 適用場景 | 特點 |
| dbmssocn | TCP/IP | 跨網路、預設、效能佳 | 可指定埠、支援加密、IPv6 |
| dbnmpntw | Named Pipes | 區域網路、舊版相容 | 利用 SMB/IPC$,需開放 445/139 |
| dbmsrpcn | Multiprotocol (RPC) | 舊版跨協定 | 已棄用 |
| dbmsvinn | NWLink IPX/SPX | Novell 網路 | 極少用 |
| dbmslpcn | Shared Memory | 本機連線 | 繞過網路堆疊,延遲最低,CPU 限制 |
Shared Memory Net-Library 進階
- 啟用條件:客戶端與伺服器**同一台實體機器**。
- 連線字串指定方式:
- 伺服器名稱用 `.` 或 `(local)` 或 `localhost`
- 或加前綴 `lpc:` (如 `lpc:MyInstance`)
- 原理:Windows 共享記憶體 + 同步物件 (Mutex/Event),避免網路堆疊開銷。
- ⚠️ **不一定最快**:高併發本機連線可能因同步爭用、UMS 排程器綁定導致擴展性瓶頸。生產環境建議壓測對比 TCP/IP (回環介面) 表現。
3. 連線建立與 UMS 排程器綁定
- 啟動時,SQL Server 為每個邏輯 CPU 建立一個 **UMS 排程器 (Scheduler)**。
- 新連線指派給**目前連線數最少**的排程器,**終生綁定** (斷線前不換)。
- 應用層含義:若應用建立多連線 (連線池),工作負載可能不均勻集中於少數排程器 → CPU 熱點。對策:
- 調整連線池大小,避免過多連線。
- 重新連線 (重啟應用/清空連線池) 觸發重新分佈。
- 監控 `sys.dm_os_schedulers` 識別負載傾斜。
4. 連線記憶體配置
- 每連線保留 **3 個網路封包緩衝區**。
- 緩衝區大小 = `sp_configure 'network packet size'` (預設 4KB)。
- 記憶體來源:
- 封包大小 < 8KB → **緩衝集區** (Buffer Pool)
- 封包大小 ≥ 8KB → **MemToLeave** 區域 (非緩衝集區虛擬位址空間)
- 實務差異:`SqlClient` 預設 8KB → MemToLeave;經典 ADO (SQLOLEDB) 預設 4KB → Buffer Pool。大封包減少網路往返,但增加 MemToLeave 壓力,需權衡。
5. 事件類別:語言事件 vs RPC 事件
| 類別 | 觸發方式 | 範例 | 執行計劃重用 |
| Language Event | T-SQL 批次字串 | `CommandType=Text`、`SELECT * FROM T` | 依賴自動參數化 (有限、不穩定) |
| RPC Event (Remote Procedure Call) | 預存程序 / 參數化命令 | `CommandType=StoredProcedure`、`sp_executesql` 參數化 | **顯式參數化,計劃穩定重用** |
最佳實務:盡可能使用 RPC (參數化/預存程序)。優點:
- 避免非參數化查詢產生大量單用計劃佔用 Plan Cache。
- 減少編譯 CPU、鎖定 Plan Cache 旋轉門鎖。
- 防止 SQL 注入。
- 網路封包更小 (僅傳參數值)。
故障排查決策樹
- 連線失敗 → 確認 Net-Library 順序、防火牆、埠、Browser 服務、別名設定。
- 效能差 → 檢查是否使用 Language Event 大量非參數化查詢 → 改 RPC/參數化。
- 記憶體壓力 → 檢查連線數 × 封包大小 × 3 是否擠佔 Buffer Pool / MemToLeave。
- CPU 熱點 → 檢視 `sys.dm_os_schedulers` 排程器負載分佈,調整連線池/親和性。
小結
理解「API 層 → Net-Library → 協定 → UMS 排程器 → 事件類型」完整鏈路,能將連線問題精準定位到具體層級,並從架構層面優化效能與安全性。**現代開發首選 `SqlClient` + 參數化 RPC + TCP/IP**,兼具效能、安全、可診斷性。
- 上一篇文章: SQL Server 伺服器異常行為檢測:木馬、惡意軟體與效能異常全排查指南
- 下一篇文章: SQLCLR 開發系列(五):自訂聚合函數實作指南
Copyright ©
程式碼之家 All Rights Reserved