Dot-Net

使用編譯查詢時我們還需要儲存過程嗎?

  • April 10, 2013

在實體框架(或 linq-to-sql)中結合 SQL Server 使用編譯查詢時,使用儲存過程實際上是否還有性能優勢?

編譯後的查詢將被記憶體為參數化查詢,因此性能應該接近於儲存過程。是否存在儲存過程會執行得更好的情況?

  • 編輯 -

在回應 Yakimych 下面的回答時,我並不是要暗示編譯查詢與儲存過程相同。如果您在應用程序端完成了所有可能的優化(在本例中為編譯查詢),我試圖弄清楚是否仍然需要儲存過程。所以我想我正在尋找為什麼儲存過程比應用程序端優化和參數化查詢的組合更好的原因(這是有效的編譯查詢)。

我問這個的原因之一是因為有很多人似乎認為由於不同的原因(即這篇文章)不再需要儲存過程。

“在任何情況下儲存過程會執行得更好嗎?”

給定在 EF 或儲存過程中生成的可比較的參數化 SQL,它們將執行相同的操作。

但是,DBA 總是有機會根據他們對 DB 模式及其使用模式的經驗進一步優化查詢。儲存過程允許他們在隔離使用它的應用程序的情況下輕鬆地做到這一點,而 ORM 則不然。

我們有一個極其複雜的 SQL Server 數據庫,其中有許多外部系統通過觸發器將數據複製進出。EF 對我們的問題是,在使用任何 ORM 而不是 DBA 時,對 DB 觸發的 SQL 的責任將成為應用程序開發人員的責任。

首先,編譯 EF 查詢與使用儲存過程可以實現的性能優勢無關。

根據http://msdn.microsoft.com/en-us/library/cc853327.aspx - 當針對概念模型執行查詢時會發生以下操作:

  • 載入元數據
  • 打開數據庫連接
  • 生成視圖
  • 準備查詢
  • 執行查詢
  • 載入和驗證類型
  • 追踪
  • 物化對象

以及有關的解釋Preparing the query

包括編寫查詢命令、基於模型和映射元數據生成命令樹以及定義返回數據的形狀的成本。因為 Entity SQL 查詢命令被記憶體,相同查詢的以後執行花費更少的時間。您還可以使用已編譯的 LINQ 查詢來降低以後執行的成本。

因此,如果您編譯查詢並在以後重新使用它,那麼您會在每次後續查詢執行期間節省應用程序中此操作的時間。但是,您不做的是不影響針對數據庫執行的生成的 SQL 程式碼。編譯查詢時獲得的性能優勢是在應用程序級別。

另一方面,您通常會使用儲存過程,以防您對生成的 SQL 程式碼不滿意並希望在數據庫級別優化性能。

編輯以回應您的評論和編輯。

在我看來,您的印像是編譯 EF 查詢會以某種方式更改將針對數據庫執行的生成的 SQL 程式碼(您提到編譯的查詢會導致參數化的 SQL 查詢?)。事實並非如此。無論您是直接執行查詢還是使用查詢compiledQuery.Invoke都將對數據庫執行相同的 SQL 程式碼。此外,您無法完全控制它,而是依靠 ORM 以最佳方式生成它。在某些情況下,它不是最優的,這就是 SP 的用武之地。

所以總結一下:

  • 編譯查詢純粹是應用程序端的優化。它節省了編譯在程式碼中重複使用的查詢的時間。
  • 儲存過程可用於調整您的 SQL 程式碼並使其盡可能接近您的目標,從而提供在數據庫級別獲得最佳性能的可能性。

絕不是一種技術可以替代另一種技術。

引用自:https://stackoverflow.com/questions/3802098