DataTable.Select与List<T> LINQ性能比较

4
我有一个应用程序,它执行SQL并将一组数据加载到数据表中。作为处理的一部分,有6或7个DataTable.Select()来过滤一些数据。每个需要处理的项目需要300毫秒。有5000个项目需要处理,所以需要25分钟。这是不可接受的。
创建POCO并将它们加载到List中,然后使用LINQ查询列表是否比使用DataTable.Select更快?
谢谢。
更新:我深入研究了一下,发现有两个数据表,每个表约有15000条记录。用于填充数据表的2个查询每个需要1秒。然后需要25分钟循环遍历字典的值属性中的5000个项目,并进行5次DataTable.Select操作。
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()和在List上使用LINQ实际上会做相同的事情。您需要重新考虑您的逻辑,也许通过添加一些缓存来优化?您还可以提供一些筛选的示例。例如,如果您正在使用Select查找单个行,则通过单个循环逐行遍历数据集可能更有效率。 - mellamokb
选择方法的筛选模式是什么?在我看来,这需要太长时间。 - Petr Abdulin
不要猜测性能问题,拿出一个分析器并测量它们。 - Juliet
请问您能推荐一个易于理解/设置的分析器吗? - Jon
4个回答

6

有趣的是,您的问题中没有与"SQL"相关的标签。我建议您学习如何使用SQL语言及其好处。根据您的说法,很可能您正在使用代码创建大量笛卡尔积, 而不是利用关系型数据库的功能(连接,索引等)。

使用DataTable或List等交叉连接始终会导致性能严重下降,无论使用哪种语言或平台。

话虽如此,您仍然可以使用LINQ,因为它能够动态地生成智能SQL,但仍要避免在IEnumerable(T)上使用ToList()、ToArray()等类似扩展方法,这会召唤出所有底层数据(尽可能从头到尾保持可枚举并利用"对象流")。如果您真正理解什么是关系型数据库以及如何高效地使用它,那么您将成为更好的LINQ开发人员。


没有 SQL 问题,查询 15000 行只需要 1 秒钟。 - Jon
4
Simon的意思是,在您的应用程序中进行这种数据操作会很慢且占用内存。正如您所说,数据库很快,为什么不让它完成所有工作呢? - Andrew Charlton

3
几乎任何东西都比操作ADO.NET DataTable快得多 - 从任何意义上讲,它们都不是为了快速检索而设计的。您还应该将对象放入适当的数据结构中; DataTable是一棵红黑二叉树,如果您不想要它,请不要使用它。
如果您只是将DataTable用作具有字段的行的顺序集合,则仅通过将DataTable替换为List 并将Select调用替换为Where调用,您可能会看到2倍或更多的加速,尽管这取决于您正在做什么。
编辑:实际上,我改变了主意。 DataTable中5000个项目的排序或过滤与300ms的成本无关,因此瓶颈可能与此无关。

+1 谢谢。我一直在寻找验证DataTable内部是红黑树的证明。DataTable中的行有多经常被搜索?主键和外键约束可能是DataTable使用RBTrees的重要因素。但是,90%的情况下,我看到使用DataTables时,它是一个从未使用过的二维数组。当您拥有大量数据时,这使它成为可怕的数据结构。 - TamusJRoyce

0

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

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


-1
创建POCO并将它们加载到列表中,然后使用LINQ查询列表是否比使用DataTable.Select更快?
我们不清楚,因为您没有提供足够的信息。我们不知道您的方法如何编码(也许您的代码中有一个错误的Thread.Sleep(300);我们无法判断)。
更重要的是,我们需要知道瓶颈在哪里。要找出这一点,您需要一个分析器。获取一个分析器,一旦您知道瓶颈在哪里,我们可能可以帮助您获得额外的性能。
话虽如此,转换到LINQ可能不会单独解决您的性能问题。其他地方出了问题,无论是使用DataTables和LINQ编写的,都基本无关紧要。性能增益将来自于对问题攻击计划的正确选择;DataTables和LINQ只是实现该攻击计划的方式。

请问您能推荐一个易于理解/设置的分析器吗? - Jon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接