SQL Server存儲過程可以是Transact-SQL(T-SQL)語句,或者是.NET框架的公共語言運行時(CLR),它是專為方便數據庫查詢而設計的。它們接受輸入參數,返回輸出參數,可以在數據庫中執行增刪改查各種操作。存儲過程提供了大量便利,從降低網絡交通量到重用緩存執行計劃,還增強了安全性,提升了易維護性。
SQL Server 2008版本引入了一批新功能,與早期的相同產品SQL Server 2005相比,在存儲過程性能方面提供了極大的提升。三年後,2008 R2推出,該版本對存儲過程只有幾處較小的調整。而即將在今年初發布的SQL Server 2012將實現大量自身性能的提升。
存儲過程的發展
SQL Server 2008和2008 R2中存儲過程最大的提升之處是表值參數。這種參數類型可以把多行數據分組成數據集,然後把它們一次性送到數據庫服務器,減少了客戶端和服務器之間的往返交互,而且它不需要創建臨時表或者大量參數。表值參數在提取數據時不需要施加任何鎖。該功能還支持指定排序順序。
表值參數的結構很容易理解和使用,而且它可以適應復雜的業務邏輯。使用表值參數與使用傳統的存儲過程參數沒有什麼不同。首先,聲明一個用戶定義的表類型,並使用該表類型輸入參數創建存儲過程。接下來,聲明表類型變量並引用它。使用“INSERT”語句給表變量賦值,而不是使用“SET”語句或者“SELECT”語句。最後,把填充後的表變量加到存儲過程中作為輸入參數。
SQL Server 2008還新增了“MERGE”語句,支持把多個數據操縱語言(DML)操作合並到一個T-SQL語句中。在連接表上使用合適的索引,你可以得到查詢性能的提升。這是因為單個“MERGE”語句降低了數據在源表和目標表處理的時間。在SQL Server 2005以及更早的版本中,每個“INSERT”,“DELETE”和“UPDATE”語句都必須一次處理完數據。“MERGE”非常有用,比如說當你做兩個表的同步時就可以用它。
在SQL Server 2008和2008 R2存儲過程中,分組操作的功能通過“GROUPING SET”語法得到了增強。簡單的“GROUP BY”語句為所有列值的每個組合返回一行,而“GROUPING SETS”為每列的每個唯一值返回一行。沒有這個新功能的話,後者將要使用“UNION”結構為每列執行多次“GROUP BY”語句。那樣很明顯會需要更多資源,比如:磁盤IO操作、內存以及運行時間。
在存儲過程編程時,SQL Server 2008和2008 R2還可以使用新行構造器在一行“INSERT”語句中插入多行。數據庫管理員對這部分語法可能非常熟悉了:“INSERT INTO TABLE (COLa, COLb, COLc) … VALUES (V1a, V1b, V1c …), (V2a, V2b, V2c …), … (V1000a, V1000b, V1000c …)”。其中數字“1000”表示每個插入語句允許的最大行數。新的“INSERT”語法更簡介,因為它去除了重復的字符串,並通過降低網絡交通量,實現了與服務器更快的交互。
在我的第三個試驗中,我運行了10批語句,每批1000條新類型的插入,並行執行了一萬條獨立插入。每個測試算作一次交互,但是與舊式的“INSERT”相比,簡化後的行構造削減了交易數量和服務器傳送的字節數達1000倍,降低了客戶端發送數據時間三倍,客戶端處理時間300倍。整體執行時間下降超過一半。
2012年的存儲過程
在即將發布的新版本中,SQL Server存儲過程還會有一些調整。在SQL Server 2012中,通過使用列存儲索引,數據倉庫中存儲過程的性能可以加快十倍、百倍或者千倍,列存儲索引是第三方社區技術預覽流行的可擴展特性,該版本預計在今年夏季發布。列存儲索引不像傳統基於行的索引結構(也稱為“行存儲”索引),它一次對一列進行分組並存儲索引數據,因此極大地降低了查詢執行時間。
SQL Server 2012還支持開發者對大對象數據類型聯機重建索引。也就是說,在SQL Server 2008 R2以及更早的版本中,用戶不能對varchar(max),nvarchar(max)或者varbinary(max)列,或者XML數據類型聯機執行重建操作。現在,存儲過程從這些數據類型提取數據也不必等待數據庫維護窗口整理索引,因此提升了存儲過程性能。
另一項新功能是稱為“FORCESCAN”的查詢優化器提示。當SQL Server查詢優化器低估了返回行數並誤選擇了索引查找操作時,SQL Server開發者可以讓查詢掃描替代索引。這樣的話,該查詢處理花更少時間久可以完成了。
我這裡只是對於SQL Server 2008,2008 R2和2012各個版本關於存儲過程性能的特性做了一點走馬觀花的介紹。在這些SQL Server版本中還有大量細微的變化,這些變更也間接地位存儲過程性能提升做貢獻,比如:新的函數和語句,過濾索引和新的執行計劃指南。但是這裡列出的功能,不管你使用的是哪個版本,都肯定會給你的查詢帶來比以往更多的性能提升。