通過自定義函數提高服務器性能
導讀:在應用程序開發中,可以通過函數來提高系統的性能與代碼的重復利用。在SQL Server數據庫中也可以通過自定義函數來提高服務器的性能。用戶自定義函數可以從外部接受必要的參數,并在內部執行一些復雜的操作,最后返回正確的結果。這項技術的出現很大程度上簡便了人們的操作,使工作人員的工作輕松很多。
在數據庫開發中,筆者強烈建議數據庫管理員要多用用函數。只要能夠通過函數來實現的功能,那么就要用函數。或許大家還不明白其中的原因。沒有關系,現把這個原則刻在心中,然后筆者再跟大家解釋其中的奧妙。
一、利用函數來實現業務邏輯的優勢
1、 函數的執行速度比普通的SQL代碼要快。
在同等條件下,實現同樣功能的SQL代碼與把SQL代碼定義成函數,后者的執行性能要比前者高許多。這主要是因為在數據庫中,用戶自定義函數通過緩存計劃并在重執行時重用它來降低SQL代碼的編譯開銷。如現在在數據庫中需要實現一個功能,要返回企業在職員工每天遲到或者曠工的人員信息。這個功能即可以每天通過一個SQL代碼來實現。也可以把實現這個查詢的SQL代碼封裝成一個函數,然后應用程序通過調用這個函數來實現這個需求。如果通過SQL代碼來實現的話,每天查詢一次,數據庫都需要重新編譯并優化這條SQL語句。而如果通過函數來調用的話,則不需要重新解析和重新優化。因為其執行計劃只要運行過一次,就會在數據緩存中保存下來。下次需要調用這個函數的話,則直接調用緩存中執行計劃即可。可見,通過函數來實現某些常用的功能,可以避免重復的解析與優化,縮短執行時間,提高數據庫性能。
2、 模塊化設計提高數據庫與應用程序開發性能。
如上面這個例子,企業剛開始的時候可能需要查詢遲到與曠工人員的編號、姓名、職位、事由等信息。但是后來用戶的需求發生了改變,他們希望在這些信息的基礎上,還能夠帶出當月累計遲到或者曠工的次數、是否有正當手續等信息。如果在數據庫與應用程序設計開發的時候,是通過SQL代碼來實現這個功能的。那么此時筆者非常不幸的告訴大家,要實現這個需求的話,必須修改源程序中嵌入的SQL代碼。這是一件非常麻煩的工作。但是如果通過函數來實現的話,則應用程序的源代碼基本上不需要更改。而只需要在數據庫中更改這個函數的代碼。這筆更改應用程序代碼要簡單的多,時間也可以短許多。
另外,可能不僅一個地方需要用到這個SQL代碼。在日常的查詢中,在員工的績效考核系統中,在工資核算系統中都需要這些內容。如果用普通的SQL代碼來實現的話,則在各個作業中都需要重復的書寫這些代碼。顯然這個工作量非常的大。最要命的是,若以后用戶需求更改了的話,需要同時修改多個地方的代碼。顯然通過SQL代碼來實現某些需求的話,代碼的重復利用程度不高。這會影響數據庫的開發效率。而通過函數來實現的話,又有另一番新天地。因為只需要創建一次函數并將其存儲在數據庫中,那么應用程序中就可以進行多次重復調用。即使需求有改變的話,只需要更改函數,那么其他各個作業的功能也會相應的更改。
可見利用函數來實現功能,不僅可以提高數據庫運行性能,而且還可以提高數據庫與應用程序的開發效率。
3、 減少網絡流量提高數據庫運行性能。
如果利用函數來實現某些功能的話,則還可以明顯的減少網絡流量。如上面這個需要,要統計員工當月的遲到、早退、曠工次數。如果通過SQL代碼來實現的話,則需要先把員工當月每次遲到、早退、曠工的記錄返回到應用程序中,然后再在應用程序中進行相關的統計。但是如果通過函數來實現這個功能的話,則處理方式就不一樣了。利用函數來實現的話,是在數據庫中統計好相關的結果,如員工遲到的次數等等。然后直接把這個結果返回給應用程序。也就是說,用戶最終需要的是一個統計結果。而通過SQL代碼來實現的時候,數據庫需要把員工遲到、曠工等違紀信息的明細返回給應用程序。而通過函數來實現的話,則只是把最后的統計結果返回給應用程序。顯然利用函數來實現其網絡傳輸的數據量要少的多。這對于網絡帶寬受到限制的企業來說,可以通過這種方式輕而易舉的縮短用戶的等待時間。如果相關的記錄比較多,或者用戶需要通過互聯網遠程訪問數據庫的時候,這個效果特別明顯。
二、Transact-SQL 函數與CLR 函數,該用哪一種?
在SQL數據庫中,不僅可以利用數據庫自帶的Transact-SQL語言來編寫函數,而且還可以使用Microsoft .NET Framework 編程語言來編寫函數。這在很大程度上提高了函數能夠實現的功能。不過兩種語言在不同的情況下使用,對于數據庫的性能的影響是不同的。為此數據庫設計與開發人員必須了解這兩種語言的差異,并在合適的情況下選擇合適的語言。這有利于提高數據庫的性能。在SQLServer數據庫中,把利用Microsoft .NET Framework 編程語言來實現的函數,叫做CLR函數。如CRL表量值函數用來返回單個結果的值,如字符串、數字等等。那么到底還如何進行選擇呢?筆者的如下幾個建議或許能夠幫助大家。
第一個建議:客戶端運行OR服務器運行?
以前在數據庫部署的時候,由于客戶端配置的問題,往往把所有的應用都放在服務器上實現。如此的話,只要提高服務器的配置即可。但是隨著數據庫應用越來越復雜,把所有的擔子都壓在數據庫服務器上,已經讓數據庫服務器超負荷運行了。隨著客戶端硬件配置的提高,為此把一些運行時間比較長的作業放到客戶端來運行,未嘗不是分攤服務器壓力的一種好方法。如果數據庫設計與開發人員有這種想法的話,那么在選擇使用Transact-SQL 函數還是CLR 函數的問題上,就有了方向。Transact-SQL 函數與CLR 函數都可以在服務器上運行。在服務器上運行函數的話,可以將代碼與數據靠近在一起,以減少不必要的網絡流量。但是就如同上面所說的,有時會數據庫設計人員出于整體性能的考慮,不得不把一些運行時間比較長或者硬件資源耗用量比較大的作業放在客戶端上執行。但是到目前為止,Transact-SQL 函數只能夠在服務器端執行,CLR 函數的話不僅可以在服務器端運行而且還可以在客戶端上執行。所以,如果要把某個復雜的作業放在客戶端上運行,而這個作業又需要調用某個函數的話,那么在這種情況下就需要采用CLR 函數。
第二個建議:業務邏輯的復雜性?
利用函數來實現的功能,即可以是才十幾行代碼的作業,也可以是包含幾百條業務邏輯的復雜功能。在編寫函數的時候,到底是采用Transact-SQL 函數還是CLR 函數,還需要看看其業務邏輯的復雜性。因為Transact-SQL代碼雖然也可以實現一些復雜的功能,但是其畢竟不是屬于專業的開發語言。當業務邏輯比較復雜的時候,Transact-SQL代碼開發和執行的時候,效率并不是很好。如現在要給用戶利用隨機數生成密碼。在這個功能上,利用Transact-SQL代碼也可以實現,但是其代碼會很長。而利用CLR函數來實現的話,則只需要簡單的幾行。可見這個代碼的編寫量上就有很多的差別。代碼量一增加,那么后續維護的工作量也就越大。
為此為了提高函數的開發效率,對于業務邏輯比較復雜,并且可能會占用服務器比較多的CPU或者內存資源的函數,最好采用CLR函數來實現。這不僅可以簡化函數的開發,而且在有需要的時候,還可以把這個函數放在客戶端上去職執行,一舉多得。故在判斷到底采用哪種函數為好的話,還需要考慮其業務邏輯的復雜性與硬件資源的耗用情況。
總的來說,在大部分情況下,Transact-SQL 函數與CLR 函數是通用的。但是為了取得更好的性能,可以根據以上的幾個建立來判斷到底利用哪種類型的函數。另外,如果采用擴展存儲過程的話,最好也是采用CLR函數。因為擴展存儲過程與CLR函數的兼容性比較好。但是CLR函數是利用C#等編程語言開發的,對于一些數據庫管理員來說可能有一定的難度。這也可以說明,未來的數據庫開發人員,往往需要多掌握幾門語言,才能夠勝任。光靠SQL語言往往并能夠完成數據庫的全部設計與開發工作。因為業務需求對數據庫性能方面的要求越來越高。多門語言的結合使用,有利于數據庫開發者設計性能更高的數據庫應用系統,從而給用戶更快的享受,提高用戶滿意度。關于通過自定義函數提高服務器性能的問題就為大家講述到這,希望文中的內容能夠幫到大家。
【編輯推薦】


















