簡體   English   中英

為什么EF查詢數據需要這么長時間才能加載到內存中?

[英]Why is EF query data taking so long to load into memory?

我有一段代碼可以執行一個很大的查詢,有很多聯接,等等。為簡單起見,這里大概有以下結構:

var rootQuery = MainQuery(); // IQueryable<MyClass>
var jq1 = JoinQuery1(); // IQueryable<anonymous type>
var jq2 = JoinQuery2();
...
var jq6 = JoinQuery6();
var bigQuery = from x in rootQuery
               join j1 in jq1 on x.ID equals j1.MainID into join1
               from j1 in join1.DefaultIfEmpty()
               join j2 in jq2 on x.ID equals j2.MainID into join2
               from j2 in join1.DefaultIfEmpty()
               ...
               join j6 in jq6 on x.ID equals j6.MainID into join6
               from j6 in join1.DefaultIfEmpty()
               select new {
                            x.ID,
                            x.Field1,
                            j1.FieldA,
                            j2.FieldB,
                            ...
                            j6.FieldF
                          };
var sw = Stopwatch.StartNew();
var loadedData = bigQuery.ToList();
sw.Stop();
Console.WriteLine("Time Elapsed = {0} ms", sw.ElapsedMilliseconds);

秒表顯示已過去30秒,返回9行和大約30列數據(無文本字段)。 因此,我使用SQL Server Profiler嗅探了該查詢,的確是一個龐然大物。 我擺弄和試着優化了一些索引,並在200毫秒內執行了查詢。 但是,當我運行代碼時,即使SQL Profiler說查詢部分花費的時間不到200毫秒,運行.ToList()仍需要30秒鍾以上!

這里發生了什么? 為什么.ToList需要這么長時間才能將這么小的數據集加載到內存中?

編輯:我解決了該問題(請參閱下面的答案 ),但我不滿意。 對任何可以提出更好方法的人,或者至少解釋一下為什么對象實現如此昂貴以至於運行7個獨立的查詢並將它們加入本地內存的成本要低一些,這是功勞。

這似乎很違反直覺,但是我通過單獨運行IQueryables(使用Jon Skeet的整潔NullOr擴展名)解決了這個問題:

var rootQuery = MainQuery().ToList();
var jq1 = JoinQuery1().ToList();
var jq2 = JoinQuery2().ToList();
...
var jq6 = JoinQuery6().ToList();
var bigQuery = from x in rootQuery
           join j1 in jq1 on x.ID equals j1.MainID into join1
           from j1 in join1.DefaultIfEmpty()
           join j2 in jq2 on x.ID equals j2.MainID into join2
           from j2 in join1.DefaultIfEmpty()
           ...
           join j6 in jq6 on x.ID equals j6.MainID into join6
           from j6 in join1.DefaultIfEmpty()
           select new {
                x.ID,
                x.Field1,
                FieldA = j1.NullOr(j=>j.FieldA),
                FieldB = j2.NullOr(j=>j.FieldB),
                ...
                FieldF = j6.NullOr(j=>j.FieldF)
              };

現在,SQL端總共需要更長的時間(往返更多),但是至少Linq-To-Entities端實際上是瞬時的。

對任何可以解釋這種奇怪行為的人都表示感謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM