2014-11-02 80 views
1

我做上使用通配符(該contains擴展名)數據庫表中的搜索下面是代碼LINQ與大型數據庫表提高性能SQL

// This gets a list of the primary key IDs in a table that has 5000+ plus records in it 
List<int> ids = context.Where(m => m.name.ToLower().Contains(searchTerm.ToLower())).Select(m => m.Id).ToList(); 


// Loop through all the ids and get the ones that match in a different table (So basically the FKs..) 
foreach (int idin nameId) 
{ 
    total.AddRange(context2.Where(x => x.NameID == id).Select(m => m.Id).ToList()); 
} 

在有什麼我可以在LINQ改變那會導致ID更快?

感謝

+0

在'context2'的item類中,是否存在對'name','context1'的item類的引用?換句話說,謂詞中可能有'x.Name.name'? – Yogu 2014-11-02 17:06:55

+0

不,Context2具有Context1的PK的FKS,在COntext2中使用虛擬類型會更快嗎?所以'Context.name.where..' – user3428422 2014-11-02 17:10:42

+0

我不認爲這會更快,但更具可讀性。 – Yogu 2014-11-02 17:16:36

回答

1

我沒有測試它,但你可以做的東西沿着這些路線:

var total = 
    from obj2 in context2 
    join obj1 in context1 on obj2.NameID equals obj1.Id 
    where obj1.name.ToLower().Contains(searchTerm.ToLower()) 
    select obj2.Id 

它加入兩個表,首先執行笛卡爾乘積,然後將其限制於對,其中NameId的比賽(參見this tutorial on the join clause)。 where行會執行實際的過濾。

它應該更快,因爲整個匹配在數據庫中完成,並且只返回正確的ID。

如果你有在保存到context1項目的引用context2項目類Name屬性,你可以寫它更易讀:

var total = context2 
    .Where(x => x.Name.name.ToLower().Contains(searchTerm.toLower())) 
    .Select(x => x.ID); 

在這種情況下,LINQ到SQL會自動做join爲你。

+0

當然,我正在做2個查詢,因爲我可以使用一個連接,正如你正確地指出的那樣。需要使用您發佈的LINQ風格。我猜它更像SQL。謝謝! – user3428422 2014-11-02 17:27:43

+0

實際上,您正在爲與搜索字符串匹配的每個名稱進行一次查詢,因此對於搜索字詞很短的查詢很多。 – Yogu 2014-11-02 17:31:20

0

在性能方面,您可以看到測試顯示是否在1 000 000個條目中搜索1個字符串,大約100 ms。

這裏是link與測試和實施。

for (int y = 0; y < sf.Length; y++) 
    { 
     c[y] += ss.Where(o => o.Contains(sf[y])).Count(); 
    }