應用程式透過 API 或物件庫層連接 Microsoft SQL Server。常見 API 包含 ODBC、DB-Library;物件庫則有 OLE DB、ADO、ADO.NET。由於 ADO 底層使用 OLE DB,Windows 應用程式實際上主要使用 OLE DB 與 ADO.NET 兩大物件庫。現代應用程式多透過物件庫而非 ODBC 連接 SQL Server,本文將從 ADO/OLE DB 與 ADO.NET 角度剖析用戶端連線架構。
OLE DB 用戶端(消費者)透過用戶端提供者與伺服器溝通。提供者是一組 COM 元件,負責將應用程式請求轉換為網路 IPC 請求。SQL Server 最常用的 OLE DB 提供者為 SQLOLEDB,隨 SQL Server 安裝,屬 MDAC 元件一部分。
ADO 應用程式先用 Connection 物件建立連線,連線字串指定 OLE DB 提供者及參數。使用 SQLOLEDB 時字串會出現「SQLOLEDB」。ADO 也可透過 ODBC 連線,此時使用「適用於 ODBC 的 OLE DB 提供者」,並在連線字串引用 ODBC 資料來源,由提供者轉呼叫 ODBC API。
ADO.NET 應用程式通常使用此原生提供者直接與 SQL Server 溝通。核心物件包括:
ADO.NET 亦可透過:
了解這三種路徑對疑難排解極有幫助,可將連線問題歸因至特定資料存取層。
Net-Library 位於 API/物件庫與網路協定之間,透明傳遞請求與回應。SQL Server 提供所有主流網路協定的 Net-Library,可用用戶端網路工具配置。支援協定含 TCP/IP、命名管道、NWLink、多協定 (RPC) 等。
利用 Windows 共享記憶體在同一實體機器的用戶端與伺服器間通訊,繞過實體網路堆疊,速度遠超其他 Net-Library。存取受同步物件保護,效能受限於核心物件排程與資料複製能力。
指定方式:連線時使用「(local)」或電腦名稱,或在執行個體名稱加前綴 lpc:。
注意:即使連接本機 SQL Server,共享記憶體不一定是最佳選項。某些情況下直接連線可能限制擴展性,務必全面測試後再決定。
用戶端連線時,SQL Server 用戶模式排程器 (UMS) 將其指派給特定排程器。啟動時每 CPU 建立一個 UMS 排程器,新連線指派給連線數最少的排程器,連線期間不會更換排程器。
若應用程式建立多連線但工作負載不均,可能導致某些 CPU 爭用而其他閒置。例如四連線雙處理器環境,連線 1、3 指派 CPU 0,連線 2、4 指派 CPU 1。若主要工作集中在連線 1、3,CPU 0 將過載而 CPU 1 閒置。解決方案:重新平衡工作負載(優於斷線重連期望不同 CPU 指派)。
SQL Server 為每個連線保留三個封包緩衝區,大小取決於 sp_configure 設定的預設網路封包大小:
.NET 提供者預設 8 KB(使用 MemToLeave),傳統 ADO 預設 4 KB(使用緩衝集區)。
連線後請求主要分兩類:
CommandType=adCmdText 執行查詢,或 adCmdTable 產生內部查詢。CommandType=adCmdStoredProc 時,提交 RPC 執行預存程序。RPC 透過顯式參數化支援執行計畫重用。首次執行產生計畫後,後續不同參數值自動重用,避免重複編譯成本。語言事件雖可自動參數化,但能力有限,某些查詢類型無法參數化,導致相同查詢產生不同執行計畫,浪費編譯資源與記憶體。
動態 T-SQL 同理:sp_executesql 透過參數化支援計畫重用,優於 EXEC()。
所有請求(RPC、語言事件等)均格式化為 TDS,即 SQL Server 用戶端與伺服器間的專用資料格式「語言」。目前支援三版本:
僅 TDS 8.0 完整支援 SQL Server 2000 功能,其他版本保持回溯相容。