我們使用EF 6.0,.NET 4.5和使用代碼第一種方法,我們的數據庫有大約170實體(表)和主表保持15萬左右的記錄 在實體框架的第一負荷約需25秒。 我想改善這個時間,因爲這太慢了,隨着記錄數量的增加,它變得越來越慢。 我試圖生成原生圖像,嘗試使用預先生成的交互式視圖,但我無法實現任何重大改進。實體框架性能緩慢
任何人都可以幫助我嗎?
謝謝。
我們使用EF 6.0,.NET 4.5和使用代碼第一種方法,我們的數據庫有大約170實體(表)和主表保持15萬左右的記錄 在實體框架的第一負荷約需25秒。 我想改善這個時間,因爲這太慢了,隨着記錄數量的增加,它變得越來越慢。 我試圖生成原生圖像,嘗試使用預先生成的交互式視圖,但我無法實現任何重大改進。實體框架性能緩慢
任何人都可以幫助我嗎?
謝謝。
可以考慮實體框架預產生映射視圖。你可以使用EF電動工具創建預先生成視圖。
使用預先生成的視圖會將生成視圖的代價從模型 加載(運行時間)移至編譯時間。雖然這可以在運行時改善啓動性能,但在開發過程中,您仍然會遇到難以生成的視圖 。有幾個額外的 技巧可以幫助降低視圖生成的成本,編譯時間和運行時間都在 。
您可以參考此爲更多地瞭解它:Entity Framework Pre-Generated Mapping Views
您可以使用緩存的實體框架,以提高應用程序的性能。
緩存有3種類型。
1對象緩存 - 在ObjectStateManager建成一個ObjectContext的 情況下保持在已經 使用實例獲取對象的記憶軌道。這也被稱爲第一級緩存,即 。
2.查詢計劃的緩存 - 重用當 查詢被執行一次以上所生成的存儲命令。
3.元數據緩存 - 通過不同的 連接到同一模型共享模型的元數據。
你可以參考這篇文章來閱讀更多關於它:Performance Considerations for EF 6
我試過使用預生成的意見,沒有幫助。 將嘗試緩存選項。 – siddhanntarora
我最近有一個運行在SSMS超快這是採取的方式,方法太長時間使用實體框架在我的C#程序運行一個簡單的查詢。
本頁面已經被極大的幫助,在一般故障排除EF性能問題:
..但在這種情況下,沒有任何幫助。所以,最後,我這樣做:
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使用EF作爲主流,在有意義的情況下使用EF作爲例外。這是一個重要的配置示例。 – Rap
您也可以在應用程序啓動時異步「加熱」您的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()。
有關更多信息,你可以閱讀:
確保啓用延遲加載 –
您真的使用代碼中的所有170個表嗎? – ErikEJ
您可以顯示一個需要很長時間才能完成的示例查詢嗎? – Vlad274