[英]How does Entity Framework entity loading work?
我一直在嘗試制作自己的實體框架(出於個人項目的考慮,出於對制作類似東西的好奇心)。
當我使用具有700k行和5列的數據表(稱為MassData
)進行Entity Framework性能測試時,我遇到了一些特別的問題,希望有人可以向我解釋。
運行以下測試:
var Context = new EntityFameworkContext();
var first = Context.MassData.Where(x => x.Id == 1);
var firstFifty = Context.MassData.Where(x => x.Id < 50).ToArray();
上下文創建需要firstFifty
毫秒,獲得first
需要firstFifty
毫秒,獲得firstFifty
需要14毫秒。
刪除'first'
,獲取'firstFifty'
大約需要210毫秒。
如果我用一個選擇所有內容的Where()
切換'first'
查詢(仍然沒有迭代),結果是相同的。
我的第一個想法是,這是將惰性數據加載到DbSet
中的DbSet
,第一個查詢枚舉了下一個訪問的數據(即使第一個查詢沒有迭代任何內容)。 這可以解釋為什么無論查詢如何,第一個總是花最少200毫秒的時間,而第二個花一樣快,甚至沒有涉及數據庫連接(“ firstFifty”作為SQL查詢最少花25毫秒的時間來運行,而不是查詢)。我在這里看到的15毫秒)。
除了加載所有MassData
之外,需要5秒鍾。 只需閱讀大約需要2.5。 因此,它無法加載所有內容,但顯然加載量超出了第一個查詢的要求。 所以很明顯我缺少了一些東西。
有人碰巧會解釋為什么
var first = Context.MassData.Where(x => x.Id == 1);
查詢加快了
var firstFifty = Context.MassData.Where(x => x.Id < 50).ToArray();
查詢?
編輯:
事實證明,它確實與延遲加載完全無關。 第一個查詢打開連接,並且(我假設)進行連接並針對數據庫表存儲實體類型的驗證。 這樣,第二個查詢就不必打開連接或進行任何驗證(如果有的話),在這種情況下,第二個查詢的持續時間可以匹配,一切都很有意義。
編輯2:
修改標題以更好地匹配最終問題的實質(延遲加載如何工作=>實體加載如何工作)。
因為您仍在加載實體類型及其先決條件。 無論您要查詢什么。 EF的Lambda表達式仍然是SQL,從Lambda轉換為String子句和語句。 因此,第一個慢點不是來自查詢,而是來自EF初始設置。
請記住,您仍在創建EF的實例,因此它將占用一些運行時過程。 剩下的就是查詢獲取時間。 由於CLR過程,這是不可避免的過程。
因此,通常。 第二個查詢已准備好進行查詢,因為在您設置EF的模型中,該查詢仍在使用中,但是當Garbage集合決定在任何地方都不使用它時,下一個會話的查詢速度將變慢EF的開始Init。 如此簡單的“從數據庫指示您的連接仍處於打開狀態”。
有一些工具可以顯示sql服務器的活動,因此您不必猜測(例如,用於Microsoft sql server的sql profiler)。 但是第一次查詢的滯后可能與數據庫無關,這只是EF內部初始化。 EF眾所周知是懶惰的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.