我有一個場景導致運行很長的進程,並懷疑它是我們使用LINQ to Entity。要LINQ或不LINQ:關於LINQ到實體/ SQL /對象
背景: 項目正在使用LINQ To Entity和Repository模式將數據公開給我們的邏輯層。這是如何,不會改變。
ISSUE: 某種情況已經出現,需要從輸入和其他表中選擇相交的數據。爲了優化這個,我首先向數據庫查詢了一個我打算用於獲取相交數據的ID數組。我還有另一個用於我的LINQ表達式的整數數組。然後,我建立一個表達式,從LINQ中的表中選擇數據並在其中包含方法。這需要很長時間才能執行。幾乎一分鐘。
爲了對抗這一點,我嘗試了幾乎所有幾乎相同時間的LINQ技術。爲了提供信息,下面是我的一些方法的示例。
// FYI: tableTotalsIds contains 14,856 IDs as an example, built from a repository call
var tableTotalsIds = tableTotals.Select(s => s.Id).ToArray();
int[] ages = {25, 26, 27};
Expression<Func<TotalAgeCounts, bool>> ageFilter =
af => af.TableTotalsId != null &&
tableTotalsIds.Contains(af.TableTotalsId.Value) &&
ages.Contains(af.Age);
var directStartTime = DateTime.Now;
var directFetch = _ctx.TotalAgeCounts.Where(ageFilter).ToList();
var directBenchMark = DateTime.Now.Subtract(directStartTime).TotalSeconds;
var repositoryStartTime = DateTime.Now;
var repositoryFetch = _totalAgeCountsRepository
.SelectAll(new Specification<TotalAgeCounts>(ageFilter));
var repositoryBenchMark = DateTime.Now.Subtract(repositoryStartTime).TotalSeconds;
在所有情況下,查詢時間大約需要1分鐘。跳到我身上的是在.Contains()方法中使用的大量tableTotalsIds,但我不知道其他LINQ方法來實現此目的。
在LINQ中有更好的方法嗎?
目前我正在考慮將此查詢作爲簡單連接放回數據庫中,並跳過此處的LINQ瓶頸。但首先我會嘗試將未過濾的數據拉入內存,然後使用LINQ將數據連接在一起,看看會有多高效。
我對其他人如何克服類似瓶頸而不重寫應用程序的體系結構感興趣。
SOLUTION
正如批評家指出,LINQ優化沒有發生由於我.ToArray()。問題變得更深了,因爲我正在使用我們的Repository實現來構建tableTotalsIds,該tableTotalsIds已經將結果投給了IList,從而失去了進一步的LINQ/SQL優化。只需不使用我們的Repository實現來構建tableTotalsIds並直接查詢dataContext,將結果留作IQueryable即可解決問題。
您是否首先從數據庫中獲取總ID?你需要將它們拉回來,然後將它們反饋回LINQ,或者你可以在數據庫上做所有的事情嗎?如果在tableTotalsId上放置'ToArray',會發生什麼? – Rup
@rup完全是我的第一個想法。「優化」似乎是這個問題的重要組成部分。在這裏運行的查詢沒有什麼複雜的。 –
目前,這些ID是從數據庫中提取的(這似乎是浪費時間)。 ToArray在那裏阻止它重新查詢,所以我認爲它應該使其更快,如果有的話。獲取ID不需要很長時間,其後面的查詢就可以完成。 – Arkiliknam