準備 SQL 陳述式
SQL Server 2005 關聯式引擎在執行 SQL 陳述式之前,會先導入準備陳述式的完整支援。如果應用程式需要執行 SQL 陳述式數次,它可以使用資料庫 API 來執行下列動作:
- 準備一次陳述式。這可將 SQL 陳述式編譯成執行計劃。
- 在每次需要執行陳述式時,執行先行編譯的執行計劃。這樣就不必在第一次之後的每一次執行時重新編譯 SQL 陳述式。
準備和執行陳述式是由 API 函數和方法所控制。這並不是 Transact-SQL 語言的一部分。SQL Native Client OLE DB Provider 和 SQL Native Client ODBC 驅動程式支援執行 SQL 陳述式的準備/執行模型。當產生準備要求時,提供者或驅動程式會將含有要求的陳述式傳給 SQL Server,以準備陳述式。SQL Server 會編譯執行計劃,並將該計劃的控制代碼傳回給提供者或驅動程式。當產生執行要求時,提供者或驅動程式會將要求傳給伺服器,以執行與控制代碼相關聯的計劃。
準備陳述式無法用來在 SQL Server 2005 上建立暫存物件。準備陳述式也無法參考可建立暫存物件 (如暫存資料表) 的系統預存程序。這些程序必須直接執行。
過度使用準備/執行模型會降低效能。如果陳述式只執行一次,則直接執行只需要一次網路往返到伺服器。如果先準備再執行只執行一次的 SQL 陳述式,便需要多一次網路往返:一次用來準備陳述式,一次用來執行陳述式。
如果使用參數標記,則準備陳述式會更有效率。例如,假設應用程式偶而被要求從 AdventureWorks 範例資料庫擷取產品資訊。應用程式有兩種方式可以達成此目的。
使用第一種方式,應用程式可以針對所要求的每個產品執行不同的查詢。
SELECT * FROM AdventureWorks.Production.Product
WHERE ProductID = 63
使用第二種方式,應用程式會執行下列動作:
準備含有參數標記 (?) 的陳述式:
SELECT * FROM AdventureWorks.Production.Product WHERE ProductID = ?
繫結程式變數與參數標記。
每次需要產品資訊時,以索引鍵值填入繫結變數,然後執行陳述式。
如果陳述式執行超過三次以上,則使用第二種方式會比較有效率。
在 SQL Server 2005 中,準備/執行模型沒有比直接執行具有顯著的效能優勢,這是因為 SQL Server 2005 重複使用執行計劃的方式。SQL Server 2005 具有有效演算法,使目前 SQL 陳述式與針對相同 SQL 陳述式先前執行而產生的執行計劃相符合。如果應用程式多次執行具有參數標記的 SQL 陳述式,則 SQL Server 2005 將自第一次執行之後,在第二次以及後續的執行中重複使用執行計劃 (除非程序快取中的計劃過期)。但準備/執行模型仍然具有以下優點:
- 利用識別代碼來尋找執行計劃,比用演算法來使 SQL 陳述式與現有執行計劃相符更具效率。
- 應用程式可以控制何時建立及重複使用執行計劃。
- 準備/執行模型可以移至其他資料庫使用,包括舊版的 SQL Server。
在舊版的 SQL Server 中準備與執行
SQL Server 6.5 版及更早的版本不直接支援準備/執行模型。不過,SQL Server ODBC 驅動程式可透過使用預存程序來支援準備/執行模型:
- 當應用程式要求需準備 SQL 陳述式時,ODBC 驅動程式會在 CREATE PROCEDURE 陳述式中包裝 SQL 陳述式,然後將它傳送到 SQL Server。
- 當產生執行要求時,ODBC 驅動程式會要求 SQL Server 執行所產生的預存程序。
在 SQL Server 6.5 和 SQL Server 6.0 中,所產生的預存程序儲存在 tempdb 中當做暫存的預存程序。由於 SQL Server 4.21a 版及更早的版本並不支援暫存的預存程序,因此驅動程式會產生儲存在目前資料庫中的一般預存程序。SQL Server 2000 中所含的 Microsoft OLE DB Provider for SQL Server 和 SQL Server ODBC 驅動程式,在連接到 SQL Server 6.5 版、SQL Server 6.0 版和 SQL Server 4.21a 版時,會遵循這項行為。