如何让这个LINQ查询更快?

时间:2015-11-18 14:01:58

标签: c# performance linq

modelData在列表中有100,000个项目。

我在2个循环中做2“选择”。

它的结构可能不同 - 因为需要很长时间 - 10分钟

&str

5 个答案:

答案 0 :(得分:4)

我相信使用group by的两个查询可以实现你想要的。一个用于按日期创建查找,另一个用于为您提供名称日期分组项目。

var data = modelData.Where(x => x.real.Equals(1))
                    .GroupBy(x => new { x.DT.Date, x.name });
var byDate = modelData.Where(x => x.real.Equals(1))
                      .ToLookup(x => x.DT.Date);

foreach(var item in data)
{
    var aDate = item.Key.Date; 
    var aName = item.Key.name;
    var namesRealTrades = item.ToList();
    var dateRealTrades = byDate[aDate].ToList();

    // DO MY PROCESSING
}

第一个查询将为您提供按名称和日期分组的项目以进行迭代,第二个查询将为您提供查找以获取与给定日期关联的所有项目。第二个使用查找,以便列表迭代一次,并使您可以快速访问生成的项目列表。

这可以大大减少您从当前所拥有的内容中迭代modelData的次数。

答案 1 :(得分:0)

您可以像这样重写for循环:

foreach (var namesRealTrades in names.Select(aName => dateRealTrades.Where(x => x.name.Equals(aName))))
{
   //DO STUFF
}

根据您的数据,这可能会减少您必须进行的查询次数

答案 2 :(得分:0)

您是否尝试按照MSDN网站上的建议编译查询?

  

当您的应用程序执行结构相似时   多次查询,通常可以通过编译来提高性能   一次查询并用不同的次数执行几次   参数。例如,应用程序可能必须检索所有   位于特定城市的客户,指定城市   用户在表单中运行时。 LINQ to SQL支持使用   为此目的编译的查询。

https://msdn.microsoft.com/en-us/library/bb399335(v=vs.110).aspx

答案 3 :(得分:0)

有几件事:

  • 使用.ToList()计算一次序列,以便以后保留它。
  • 使用.GroupBy()来避免为已经找到的东西重新搜索modelData。

    // Collections of models having the same Date or Name.
    var dates = modelData.GroupBy(x => x.DT.Date);
    var names = modelData.GroupBy(x => x.Name);
    
    foreach (var modelsWithDate in dates)
    {
       var aDate = modelsWithDate.Key;
       var dateRealTrades = modelsWithDate.Where(x => x.real == 1).ToList();
    
       foreach (var modelsWithName in names)
       {
           var aName = modelsWithName.Key;
           var namesRealTrades = modelsWithName.ToList();
    
           // DO MY PROCESSING
       }
    }
    

答案 4 :(得分:0)

代码无效的方法有两种。

  • 姓名已经进行了评估。每次迭代它时,都必须通过整个数据再次查找所有不同的名称。你应该保存结果。
  • 您可以从集合中找到不同的值,然后再次针对每个不同的值进行集合,并查看其出现的情况。你应该使用分组。

重写的代码可能如下所示

    var dates = modelData.GroupBy(x => x.DT.Date);
    var names = modelData.Select(x => x.name).Distinct().ToArray();

    foreach (var date in dates)
    {
        var dateRealTrades = date.Where(x => x.real.Equals(1)).ToArray();
        var namesRealTradesLookup = dateRealTrades.ToLookup(x => x.name);

        foreach (var aName in names)
        {
            var namesRealTrades = namesRealTradesLookup[aName];

            // DO MY PROCESSING
            // var aDate = date.Key;
        }
    }

如果你没有在日期/名称组合中没有真正的交易,没有真正的交易,可以用更简单的方式完成

    var realModelData = modelData.Where(x => x.real.Equals(1));

    foreach (var dateRealTrades in realModelData.ToLookup(x => x.DT.Date))
    {
        foreach (var namesRealTrades in dateRealTrades.ToLookup(x => x.name))
        {

            // DO MY PROCESSING
            //var aDate = dateRealTrades.Key;
            //var aName = namesRealTrades.Key;
            //foreach(var trade in namesRealTrades) { ...
            //foreach(var trade in dateRealTrades) { ...
        }
    }