在DataTable的哪些条款下LINQ性能降低?

时间:2015-04-05 18:46:29

标签: c# performance linq datatable

我正在使用MySqlDataAdapter将MySQL中的表转储到DataTable对象中。数据库输入和输出正常,但我的应用程序代码似乎有一个性能问题,我能够追踪到特定的LINQ语句。

目标很简单,在DataTable的内容中搜索与特定字符串匹配的列值,就像传统的WHERE column = 'text' SQL子句一样。

简化代码:

foreach (String someValue in someList) {
    String searchCode = OutOfScopeFunction(someValue);
    var results = emoteTable.AsEnumerable()
        .Where(myRow => myRow.Field<String>("code") == searchCode)
        .Take(1);
    if (results.Any()) {
        results.First()["columnname"] = 10;
    }
}

此简化代码执行数千次,someList中的每个条目执行一次。当我运行Visual Studio Performance Profiler时,我发现“results.Any()”行突出显示占用了93.5%的执行时间。

我已经尝试了几种不同的方法来优化此代码,但没有一种方法在保持emoteTable DataTable作为数据主要来源的同时提高了性能。我可以在foreach之外将emoteTable转换为Dictionary<String, DataRow>,但之后我必须保持DataTable和Dictionary同步,这仍然是性能改进,但感觉不对。

三个问题:

  1. 这是在DataTable中搜索值的正确方法(相当于传统的SQL WHERE子句)吗?如果没有,应该怎么做?
  2. 1的附录,无论正确的方式,最快的(执行时间)是什么?
  3. 为什么results.Any()行消耗90%以上的资源?在这种情况下,更有意义的是var results行应该消耗资源,毕竟,它是执行实际搜索的行,对吗?
  4. 感谢您的时间。如果我找到答案,我也会在这里发布。

2 个答案:

答案 0 :(得分:0)

Any()占用了90%的时间,因为resultonly executed when you call Any()。在致电Any()之前,实际上并未进行查询。

看起来问题是你首先将整个表格取入内存然后进行搜索。您应该指示您的数据库进行搜索 此外,当您致电results.First()时,将再次执行整个results查询。

考虑到延迟执行,您应该编写类似

的内容
var result = emoteTable.AsEnumerable()
    .Where(myRow => myRow.Field<String>("code") == searchCode)
    .FirstOrDefault();

if (result != null) {
    result["columnname"] = 10;
}

答案 1 :(得分:0)

您实施的内容几乎是加入:

var searchCodes = someList.Select(OutOfScopeFunction);
var emotes = emoteTable.AsEnumerable();

var results = Enumerable.Join(emotes, searchCodes, e=>e, sc=>sc.Field<String>("code"), (e, sc)=>sc);

foreach(var result in results)
{
   result["columnname"] = 10;
}

Join可能会使用某种查找来优化对两个列表的访问。

但我要做的第一件事就是彻底放弃组合DataTable和LINQ的想法。它们是两种不同的技术,并试图断言它们在合并时可能会做什么很难。

您是否尝试过进行原始UPDATE调用?您希望更新多少项?