2015-11-16 52 views
0

我想查詢一個嵌套linq查詢表。我的查詢工作,但速度太慢。我有近40萬行。此查詢爲1000行工作10秒。對於400k,我認爲它大約需要2個小時。有沒有更快的方式來處理嵌套linq查詢?

我有這樣

StudentNumber - DepartmentID 
n100 - 1 
n100 - 1 
n105 - 1  
n105 - 2 
n107 - 1 

我想這有不同的部門ID的學生行。我的結果看起來像這樣。

StudentID - List 
n105 - 1 2 

而我的查詢提供了它。但是慢慢地。

var sorgu = (from yok in YOKAktarim 
    group yok by yok.StudentID into g 
    select new { 
     g.Key, 
     liste=(from birim in YOKAktarim where birim.StudentID == g.Key select new { birim.DepartmentID }).ToList().GroupBy (x => x.DepartmentID).Count()>1 ? (from birim in YOKAktarim where birim.StudentID == g.Key select new { birim.DepartmentID }).GroupBy(x => x.DepartmentID).Select(x => x.Key).ToList() : null, 
    }).Take(1000).ToList(); 


Console.WriteLine(sorgu.Where (s => s.liste != null).OrderBy (s => s.Key)); 

我用linqpad C#語句寫了這個查詢。

回答

2

對於400K記錄,您應該能夠將學生ID和部門ID返回到內存列表中。

var list1 = (from r in YOKAktarim 
      group r by new { r.StudentID, r.DepartmentID} into g 
      select g.Key 
      ).ToList(); 

一旦你有了這個名單,你應該能夠按StudentID並選擇那些誰擁有多條記錄的學生。

var list2 = (from r in list1 group r by r.StudentID into g 
       where g.Count() > 1 
       select new 
        { 
         StudentID = g.Key, 
         Departments = g.Select(a => a.DepartmentID).ToList() 
        } 
       ).ToList(); 

這應該是更快,因爲它只碰到一次sql數據庫,而不是數十萬次。

1

您正在迭代源集合(YOKAktarim)三次,這會使您的查詢* O(n^3)`查詢。這會很慢。

而不是回到源集合獲取組的內容,你可以簡單地遍歷g

var sorgu = (from yok in YOKAktarim 
    group yok by yok.StudentID into g 
    select new { 
     g.Key, 
     liste = from birim in g select new { birim.DepartmentID }).ToList().GroupBy (x => x.DepartmentID).Count()>1 ? (from birim in g select new { birim.DepartmentID }).GroupBy(x => x.DepartmentID).Select(x => x.Key).ToList() : null, 
    }).Take(1000).ToList(); 

但是,這仍然不是最佳的,因爲你正在做大量的冗餘子分組。您的查詢是非常等價於:

from yok in YOKAktarim 
group yok by yok.StudentID into g 
let departments = g.Select(g => g.DepartmentID).Distinct().ToList() 
where departments.Count() > 1 
select new { 
    g.Key, 
    liste = departments 
}).Take(1000).ToList(); 
+0

Downvoter正在評論? – MarcinJuraszek

+0

我還沒有投票。我想別人。 –

+0

我不是說你做了:) @İsmailHakkıŞen讓我知道現在是否更快。 – MarcinJuraszek

-3

我不能對怪物的正確性說話,只是簡單地移除除了最外面的人會解決你的問題的所有ToList()電話。

+0

這不是問題。即使沒有「ToList」調用,查詢也不是最優的。 – MarcinJuraszek

相關問題