2016-11-10 89 views
3

我們使用EF 6.0,.NET 4.5和使用代碼第一種方法,我們的數據庫有大約170實體(表)和主表保持15萬左右的記錄 在實體框架的第一負荷約需25秒。 我想改善這個時間,因爲這太慢了,隨着記錄數量的增加,它變得越來越慢。 我試圖生成原生圖像,嘗試使用預先生成的交互式視圖,但我無法實現任何重大改進。實體框架性能緩慢

任何人都可以幫助我嗎?

謝謝。

+0

確保啓用延遲加載 –

+0

您真的使用代碼中的所有170個表嗎? – ErikEJ

+0

您可以顯示一個需要很長時間才能完成的示例查詢嗎? – Vlad274

回答

1

可以考慮實體框架預產生映射視圖。你可以使用EF電動工具創建預先生成視圖。

使用預先生成的視圖會將生成視圖的代價從模型 加載(運行時間)移至編譯時間。雖然這可以在運行時改善啓動性能,但在開發過程中,您仍然會遇到難以生成的視圖 。有幾個額外的 技巧可以幫助降低視圖生成的成本,編譯時間和運行時間都在 。

enter image description here

您可以參考此爲更多地瞭解它:Entity Framework Pre-Generated Mapping Views

您可以使用緩存的實體框架,以提高應用程序的性能。

緩存有3種類型。

1對象緩存 - 在ObjectStateManager建成一個ObjectContext的 情況下保持在已經 使用實例獲取對象的記憶軌道。這也被稱爲第一級緩存,即 。

2.查詢計劃的緩存 - 重用當 查詢被執行一次以上所生成的存儲命令。

3.元數據緩存 - 通過不同的 連接到同一模型共享模型的元數據。

你可以參考這篇文章來閱讀更多關於它:Performance Considerations for EF 6

+1

我試過使用預生成的意見,沒有幫助。 將嘗試緩存選項。 – siddhanntarora

1

我最近有一個運行在SSMS超快這是採取的方式,方法太長時間使用實體框架在我的C#程序運行一個簡單的查詢。

本頁面已經被極大的幫助,在一般故障排除EF性能問題:

https://www.simple-talk.com/dotnet/net-tools/entity-framework-performance-and-what-you-can-do-about-it/

..但在這種情況下,沒有任何幫助。所以,最後,我這樣做:

 List<UpcPrintingProductModel> products = new List<UpcPrintingProductModel>(); 
     var sql = "select top 75 number, desc1, upccode " 
       + "from MailOrderManager..STOCK s " 
       + "where s.number like @puid + '%' " 
     ; 
     var connstring = ConfigurationManager.ConnectionStrings["MailOrderManagerContext"].ToString(); 
     using (var connection = new SqlConnection(connstring)) 
     using (var command = new SqlCommand(sql, connection)) { 
      connection.Open(); 
      command.Parameters.AddWithValue("@puid", productNumber); 
      using (SqlDataReader reader = command.ExecuteReader()) { 
       while (reader.Read()) { 
        var product = new UpcPrintingProductModel() { 
         ProductNumber = Convert.ToString(reader["number"]), 
         Description = Convert.ToString(reader["desc1"]), 
         Upc = Convert.ToString(reader["upccode"]) 
        }; 
        products.Add(product); 
       } 
      } 
     } 

(對於這個特定的查詢,我只是完全完全繞過了EF,以及所使用的舊的備用:System.Data.SqlClient的)

你會起皺厭惡你的鼻子;我當然這麼做了 - 但實際上這並沒有花很長時間來寫,而且幾乎立即執行。

+1

「皺我的鼻子」?這是超級聰明的。 +1使用EF作爲主流,在有意義的情況下使用EF作爲例外。這是一個重要的配置示例。 – Rap

0

您也可以在應用程序啓動時異步「加熱」您的dbcontexts以避開此問題。

protected void Application_Start() 
{ 
    // your code. 
    // Warming up. 
      Start(() => 
      { 
       using (var dbContext = new SomeDbContext()) 
       { 
        // Any request to db in current dbContext. 
        var response1 = dbContext.Addresses.Count(); 
       } 
      }); 
} 

private void Start(Action a) 
{ 
    a.BeginInvoke(null, null); 
} 

我還建議使用這樣的設置爲:(是否符合您的應用程序)

  • dbContext.Configuration.AutoDetectChangesEnabled = FALSE; dbContext.Configuration.LazyLoadingEnabled = false; dbContext.Configuration.ProxyCreationEnabled = false;

  • 跳過驗證部分(即Database.SetInitializer<SomeDbContext>(null);

  • 對GET查詢使用.asNoTraking()

有關更多信息,你可以閱讀: