数据表选择与列表 LINQ 性能

本文关键字:LINQ 性能 选择 列表 数据表 | 更新日期: 2023-09-27 17:56:23

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

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

谢谢

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

例如/

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
    {
    }
}

数据表选择与列表<T> LINQ 性能

有趣的是,没有与您的问题关联的"SQL"标签。我建议你学习如何使用SQL语言及其好处。从你所说的,很可能你正在用你的代码创建很多笛卡尔产品,而不是利用关系数据库设施(连接、索引等)。

无论使用何种语言或平台,使用数据表或列表的交叉联接或任何类似内容,都始终会导致性能严重下降。

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

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

如果您只是将DataTable用作带有字段的行的顺序集合,那么通过将DataTable替换为List<T>并将Select调用替换为Where调用,您可能会看到 2 倍或更多的加速,尽管这取决于您如何处理它。

编辑:实际上,我改变了主意。 在DataTable中对 5000 个项目进行排序或过滤时,没有任何内容意味着成本接近 300 毫秒,因此瓶颈可能无关。

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

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

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

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

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

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