我在vb.net下面有Linq查询,它需要2-3分钟才能获得3000条记录。我想优化它。请建议我
Dim sessionsEligibleForDeletion As List(Of Integer) = Nothing
以下查询需要很长时间。
sessionsEligibleForDeletion =
(From row In dt.AsEnumerable()
Group row By sessionID = row.Field(Of Int32)("sessionID") Into SessionGroup = Group
Select New With
{
sessionID,
.eligibleForDeletion = SessionGroup.Count(Function(r) r.Field(Of Int32)("sessionID")) > totalCriterias - 1
}).
Where(Function(rr) rr.eligibleForDeletion = True).
Select(Function(rr) rr.sessionID).ToList()
答案 0 :(得分:1)
所以dt
是DataTable
,首先使用AsEnumerable
代替DataTable.Select
,它会返回一个包含所有行的新DataRow()
以节省内存。
更重要的是,您从表中选择所有reportNo
,然后选择此列表中包含reportNo的所有行。这是所有行,因为您使用相同的源。所以前两个查询已经毫无意义了。
此外,您要将SessionID
的所有行分组到名为SessionGroup
的组中,这些组包含DataRows
,并且每行都有相同的SessionID
,因为您已分组通过该专栏。这就是为什么我不理解SessionGroup.Count(...sessionID)
的原因。无论如何,不会将Option Strict
设置为On
进行编译,因为Enumerable.Count
采用布尔谓词而不是整数。也许你只想使用SessionGroup.Count() > totalCriterias - 1
,所以没有谓词。
现在解决您的实际性能问题。您想查找超出SessionID
的所有totalCriterias - 1
?然后使用HashSet(Of Int32)
和Dictionary(Of int32, Int32)
的这个简单循环会更有效,只需要一个枚举:
Dim sessionsEligibleForDeletion As New HashSet(Of Integer)
Dim sessionIdCount As New Dictionary(Of Int32, Int32)
For Each row As DataRow In dt.Rows
Dim sessionID = row.Field(Of Int32)("sessionID")
Dim count As Int32
sessionIdCount.TryGetValue(sessionID, count)
count += 1
sessionIdCount(sessionID) = count
If count > totalCriterias - 1 Then sessionsEligibleForDeletion.Add(sessionID)
Next
如果您需要哈希集中的List(Of Int32)
,请使用sessionsEligibleForDeletion.ToList()
。
如果你坚持使用LINQ查询,你可以使用它:
Dim sessionsEligibleForDeletion As List(Of Int32) = dt.AsEnumerable().
GroupBy(Function(row) row.Field(Of Int32)("sessionID")).
Where(Function(grp) grp.Count() > totalCriterias - 1).
Select(Function(grp) grp.Key).
ToList()