使用LINQ查询数据表的性能非常慢

本文关键字:性能 非常 数据表 LINQ 查询 使用 | 更新日期: 2023-09-27 18:14:28

我有一个类似于这个结构的代码:我的表有108000行。这个数据表实际上只是我读取一个制表符分隔的文本文件来处理,所以我把它放在一个数据表中。

private void Foo(DataTable myDataTable)
{
        List<string> alreadyProcessed = new List<string>();
        foreach(DataRow row in myDataTable.Rows)
        {
            string current = row["Emp"].ToString().Trim();
            if (alreadyProcessed.Contains(current))
                continue;
            alreadyProcessed.Add(current);
            var empRows = from p in myDataTable.AsEnumerable
                where p["Emp"].ToString().Trim() == current
                select new EmpClass
                {
                    LastName = (string) p["lName"],
                    // some more stuff similr
                };
        // do some stuff with that EmpClass but they shouldn't take too long
        }
    }

运行这样的东西需要超过15分钟。我该如何改进呢?

使用LINQ查询数据表的性能非常慢

这是一个相当幼稚的代码重写。

我们不跟踪已经处理了哪些员工,而是按员工分组并分别处理。

var rowsPerEmployee =
    (from DataRow row in dt.Rows
     let emp = row["Emp"].ToString().Trim()
     group row by emp into g
     select g)
    .ToDictionary(
        g => g.Key,
        g => g.ToArray());
foreach (var current in rowsPerEmployee.Keys)
{
    var empRows = rowsPerEmployee[current];
    ... rest of your code here, note that empRows is not all the rows for a single employee
    ... and not just the lastname or similar
}

这将首先按员工对整个数据表进行分组,并为该员工创建一个从employee到行的字典,然后循环员工并获取行。

你应该做Group By "EMP",否则你要遍历每一行,对于一些行你要查询整个表。像这样

from p in myDataTable.AsEnumerable
group p by p.Field<string>("Emp") into g
select new { Emp = g.Key, 
             Data = g.Select(gg=>new EmpClass 
                                  { 
                                     LastName = gg.Field<string>("lName")
                                  }
                             )
           }

在linq语句中可能会减慢速度的一件事是,您选择了多少数据!你写'select new EmpClass',这取决于你选择多少列(和行/信息)作为你的输出可能会大大降低你的速度。其他解决这个问题的技巧和技巧可以在:http://visualstudiomagazine.com/articles/2010/06/24/five-tips-linq-to-sql.aspx