【问题标题】:DataTable Select vs List<T> LINQ PerformanceDataTable Select 与 List<T> LINQ 性能
【发布时间】:2011-08-23 14:16:25
【问题描述】:

我有一个执行 SQL 并将一组数据加载到数据表中的应用程序。作为处理的一部分,有 6 或 7 个 DataTable.Select() 来过滤一些数据。每个需要处理的项目需要 300 毫秒。有 5000 个项目需要处理,因此需要 25 分钟。这是不可接受的。

创建 POCO 并将它们加载到列表中,然后使用 LINQ 查询列表会比使用 DataTable.Select 更快吗?

谢谢

更新:我已经深入研究了,有 2 个数据表,每个数据表大约有 15000 条记录。用于填充数据表的 2 个查询各需要一秒钟。然后需要 25 分钟循环字典的 values 属性中的 5000 多个项目并执行 5 DataTable.Select's

例如/

foreach (OutputRecord Mailpiece in DictionaryMailpieces.Values)
{
    try
    {
        DataRow[] R = DataTable1.Select("MAILPIECE = " + Mailpiece.MailpieceSetSequenceNumber + " AND (STATUS = 4034 OR STATUS = 4037)", "DAL_DATE desc");
        if (R != null && R.Length > 0)
        {
        }
    }
    catch
    {
    }
}

【问题讨论】:

  • DataTable.Select() 和 LINQ List 将有效地做同样的事情。您需要重新考虑您的逻辑,也许通过添加一些缓存?您还可以提供一些您正在执行的过滤类型的示例。例如,如果您使用 Select 查找单个行,则在单个循环中逐行遍历数据集可能会更有效。
  • 什么是Select方法过滤模式?我认为这需要很长时间。
  • 不要猜测性能问题,拿出分析器并测量它们。
  • 请您推荐一个易于理解/设置的分析器?

标签: c# .net linq performance datatable


【解决方案1】:

有趣的是,没有与您的问题相关联的“SQL”标签。我建议,您学习如何使用 SQL 语言及其好处。根据您的说法,您的代码很可能会创建大量 Cartesian products,而不是利用 Relational Database 设施(连接、索引等)

无论使用何种语言或平台,使用 DataTables 或 Lists 或任何类似的交叉连接总是会导致严重的性能下降。

也就是说,您可以使用 LINQ,因为它能够(动态)生成智能 SQL,但您仍然希望避免调用所有基础数​​据的 IEnumerable(T) 上的所有 ToList()、ToArray() 和类似扩展方法(使其端到端可枚举,并尽可能利用“对象流”)。如果您真正了解什么是关系数据库以及如何有效地使用它,您将成为一名更好的 LINQ 开发人员。

【讨论】:

  • 不存在SQL问题,查询15000行耗时1秒
  • Simon 意识到在您的应用程序中进行此类数据操作很慢且占用大量内存。正如您所说,数据库速度很快,为什么不让它完成所有工作呢?
【解决方案2】:

几乎任何东西都比操作 ADO.NET DataTable 更快——它们在任何意义上都不是为快速检索而设计的。您还应该将对象放入适当的数据结构中; DataTable 是一棵由行组成的红黑二叉树,所以如果你不想要它,就不要使用它。

如果您只是将 DataTable 用作带有字段的行的顺序集合,那么只需将 DataTable 替换为 List&lt;T&gt; 并替换您的Select 调用与 Where 调用,虽然这取决于你用它做什么。

编辑:实际上,我改变了主意。您无法对 DataTable 中的 5000 个项目进行排序或过滤,这意味着成本接近 300 毫秒,因此瓶颈可能无关紧要。

【讨论】:

  • +1 谢谢。我一直在寻找 DataTables 在内部是 RedBlack Tree 的验证。 DataTable 中的行多久被搜索一次?那么,主键和外键约束可能是 DataTables 使用 RBTrees 的一个重要因素。但是 90% 的时间我看到使用 DataTables,它是一个从未使用过的二维数组。当你有大量数据时,让它成为一个可怕的数据结构。
【解决方案3】:

使用 LINQ 本身很可能不会显着提高速度。话虽如此,您可能会使用 PLINQ 来简化处理的并行化,这可以使其在多核系统上更好地扩展。当使用 POCO 而不是 DataTable 时,这往往要简单得多,因为 DataTable 不是线程安全的,并且存在并发问题。

话虽如此 - 我怀疑总体而言,分析此过程会给您带来更好的潜在改进,因为它可以让您找到并纠正任何瓶颈。如果没有特定的瓶颈,并且该过程只需要大量的原始处理,那么缓存也可能会有所帮助。此外,将数据留在数据库中并使用某种形式的 ORM 也可能会有所帮助,因为“6 或 7”过滤器操作可以在可扩展的服务器上而不是在本地运行。然而,所有这些都高度依赖于您的数据和算法的性质,因此需要仔细考虑才能确定总体上是有益还是有害。

【讨论】:

    【解决方案4】:

    创建 POCO 并将它们加载到列表中,然后使用 LINQ 查询列表会比使用 DataTable.Select 更快吗?

    我们不知道,你没有给我们足够的信息。我们不知道您的方法是如何编码的(也许您的代码中隐藏了错误的Thread.Sleep(300);我们无法判断)。

    更重要的是,我们需要知道瓶颈在哪里。要弄清楚这一点,您需要一个分析器。获取一个,然后一旦您知道瓶颈是什么,我们可能会帮助您获得一些额外的性能。

    也就是说,切换到 LINQ 可能无法单独解决您的性能问题。还有其他问题,是否使用DataTables 和 LINQ 进行编码大多无关紧要。性能提升将来自对问题的正确攻击计划; DataTables 和 LINQ 只是实施该攻击计划的方式。

    【讨论】:

    • 请您推荐一个易于理解/设置的分析器?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    相关资源
    最近更新 更多