如何在linq查询下进行优化

时间:2015-12-03 09:42:13

标签: vb.net performance linq optimization

我在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()

1 个答案:

答案 0 :(得分:1)

所以dtDataTable,首先使用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()