Dot-Net

實體框架太慢了。我有哪些選擇?[關閉]

  • December 1, 2011

我遵循了“不要過早優化”的口頭禪,並使用實體框架編寫了我的 WCF 服務。

但是,我分析了性能和 Entity Framework 太慢了。(我的應用程序在大約 1.2 秒內處理 2 條消息,而我正在重寫的(舊版)應用程序同時處理 5-6 條消息。(舊版應用程序為其 DB Access 呼叫 sprocs。)

我的分析指向實體框架佔用每條消息的大部分時間。

那麼,我有哪些選擇?

  • 那裡有更好的 ORM 嗎?

(僅支持對象的正常讀寫并快速完成的東西..)

  • 有沒有辦法讓實體框架更快?

注意:當我說更快時,我的意思是從長遠來看,而不是第一次通話。(第一次通話很慢(一條消息需要 15 秒),但這不是問題。我只需要它在剩下的時間裡快速的消息。)

  • 一些神秘的第三個選項將幫助我從我的服務中獲得更快的速度。

**注意:**我的大多數數據庫互動都是創建和更新。我很少選擇和刪除。

您應該從分析實體框架實際發出的 SQL 命令開始。根據您的配置(POCO、自我跟踪實體),有很大的優化空間。您可以使用該方法調試 SQL 命令(在調試模式和發布模式之間應該沒有區別)ObjectSet<T>.ToTraceString()。如果您遇到需要進一步優化的查詢,您可以使用一些預測為 EF 提供有關您嘗試完成的任務的更多資訊。

例子:

Product product = db.Products.SingleOrDefault(p => p.Id == 10);
// executes SELECT * FROM Products WHERE Id = 10

ProductDto dto = new ProductDto();
foreach (Category category in product.Categories)
// executes SELECT * FROM Categories WHERE ProductId = 10
{
   dto.Categories.Add(new CategoryDto { Name = category.Name });
}

可以替換為:

var query = from p in db.Products
           where p.Id == 10
           select new
           {
               p.Name,
               Categories = from c in p.Categories select c.Name
           };
ProductDto dto = new ProductDto();
foreach (var categoryName in query.Single().Categories)
// Executes SELECT p.Id, c.Name FROM Products as p, Categories as c WHERE p.Id = 10 AND p.Id = c.ProductId
{
   dto.Categories.Add(new CategoryDto { Name = categoryName });
}

我只是在腦海中輸入了它,所以這並不是它的執行方式,但是如果你告訴它你所知道的關於查詢的一切,EF 實際上會做一些很好的優化(在這種情況下,我們將需要類別 -名稱)。但這不像急切載入 (db.Products.Include(“Categories”)),因為預測可以進一步減少要載入的數據量。

事實是,諸如 Entity Framework 之類的產品總是很慢且效率低下,因為它們執行的程式碼要多得多。

我還發現人們建議應該優化 LINQ 查詢、查看生成的 SQL、使用調試器、預編譯、採取許多額外步驟等是愚蠢的,即浪費大量時間。沒有人說 - 簡化!每個人都想通過採取更多步驟(浪費時間)使事情進一步複雜化。

一個常識性的方法是根本不使用 EF 或 LINQ。使用純 SQL。沒有什麼問題。僅僅因為程序員之間存在從眾心理並且他們感到使用那裡的每一個新產品的衝動,並不意味著它是好的或者它會起作用。大多數程序員認為,如果他們整合了大公司發布的每一條新程式碼,就會使他們成為更聰明的程序員。一點也不真實。智能程式主要是關於如何用更少的麻煩、不確定性和最少的時間做更多的事情。記住——時間!這是最重要的元素,所以盡量不要把它浪費在解決糟糕/臃腫程式碼中的問題上,這些程式碼只是為了符合一些奇怪的所謂“模式”而編寫

放鬆,享受生活,停止編碼,停止使用額外的功能、程式碼、產品、“模式”。生命很短,你的程式碼的生命更短,這當然不是火箭科學。刪除 LINQ、EF 等層,您的程式碼將高效執行、可擴展,並且是的,它仍然易於維護。過多的抽像是一種糟糕的“模式”。

這就是您問題的解決方案。

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