入職新公司,負責維護老項目,基於3層架構,使用mvc框架,加存儲過程的老項目,學習了存儲過程的使用,思考了使用存儲過程的理由,便通過搜索資料進行了如下總結
優點
1. 運行速度:對於很簡單的sql,存儲過程沒有什么優勢。對於復雜的業務邏輯,因為在存儲過程創建的時候,數據庫已經對其進行了一次解析和優化。存儲過程一旦執行,在內存中就會保留一份這個存儲過程,這樣下次再執行同樣的存儲過程時,可以從內存中直接調用,所以執行速度會比普通sql快。
2. 減少網絡傳輸:存儲過程直接就在數據庫服務器上跑,所有的數據訪問都在數據庫服務器內部進行,不需要傳輸數據到其它服務器,所以會減少一定的網絡傳輸。但是在存儲過程中沒有多次數據交互,那么實際上網絡傳輸量和直接sql是一樣的。而且我們的應用服務器通常與數據庫是在同一內網,大數據的訪問的瓶頸會是硬盤的速度,而不是網速。
3. 可維護性:的存儲過程有些時候比程序更容易維護,這是因為可以實時更新DB端的存儲過程。 有些bug,直接改存儲過程里的業務邏輯,就搞定了。
4. 增強安全性:提高代碼安全,防止 SQL注入。這一點sql語句也可以做到。
5. 可擴展性:應用程序和數據庫操作分開,獨立進行,而不是相互在一起。方便以后的擴展和DBA維護優化。
缺點
1. SQL本身是一種結構化查詢語言,但不是面向對象的的,本質上還是過程化的語言,面對復雜的業務邏輯,過程化的處理會很吃力。同時SQL擅長的是數據查詢而非業務邏輯的處理,如果如果把業務邏輯全放在存儲過程里面,違背了這一原則。
2. 如果需要對輸入存儲過程的參數進行更改,或者要更改由其返回的數據,則您仍需要更新程序集中的代碼以添加參數、更新調用,等等,這時候估計會比較繁瑣了。
3. 開發調試復雜,由於IDE的問題,存儲過程的開發調試要比一般程序困難。
4. 沒辦法應用緩存。雖然有全局臨時表之類的方法可以做緩存,但同樣加重了數據庫的負擔。如果緩存並發嚴重,經常要加鎖,那效率實在堪憂。
5. 不支持群集,數據庫服務器無法水平擴展,或者數據庫的切割(水平或垂直切割)。數據庫切割之后,存儲過程並不清楚數據存儲在哪個數據庫中。
總結
1. 適當的使用存儲過程,能夠提高我們SQL查詢的性能,
2. 存儲過程不應該大規模使用,濫用。
3. 隨着眾多ORM 的出現,存儲過程很多優勢已經不明顯。
4. SQL最大的缺點還是SQL語言本身的局限性——SQL本身是一種結構化查詢語言,我們不應該用存儲過程處理復雜的業務邏輯——讓SQL回歸它“結構化查詢語言”的功用。復雜的業務邏輯,還是交給代碼去處理吧。