【问题标题】:Adding primary key on datatable在数据表上添加主键
【发布时间】:2015-05-05 11:15:35
【问题描述】:

我一直在尝试通过向表中添加主键来使用DataTable.Select 来提高性能,但仅 1200 行仍然需要太多时间。有主键和没有主键的时间差只有 3-4 秒(DataTable.Select)。

现在,据我所知,Linq 的性能肯定不受主键添加的影响。由于创建了 Datarow 集合数组,我猜这对我来说性能毫无用处。

那么主键到底有什么用呢?

【问题讨论】:

  • 它或多或少是与DataTable后面的后端数据库相关的东西。对于纯本地数据,pk 只会对合并等某些事情有所帮助。这种比较背后的原因是什么?在不了解更多细节的情况下,使用没有后端的 DataTable 似乎是个糟糕的选择。
  • @Ralf - a pk would only be helpfull with certain things like merging 合并什么?你可以解释吗。我的目的是在一个循环中选择 200-300 行。因此,我希望选择速度快。
  • 我不确定,但我认为 PK 是一个约束,不会创建索引。
  • 我的意思是像 DataTable.Merge 这样的函数,例如,它使用 PK 来匹配要合并的 2 个数据表之间的行。
  • @PaoloCosta 我也这么认为,甚至发布了一个较早的错误答案,但实际上,事实证明 PK 确实在内部创建了一个索引,并且可以使用该索引。

标签: c# linq select datatable


【解决方案1】:

DataTable 的主键在内部确实维护了一个索引,与行顺序分开,您是对的,Select 可以优化为将主键上的过滤器视为特殊情况。不幸的是,这还没有完成,Select 只是逐一检查所有记录并评估过滤器。

这仍然比您的 LINQ 版本慢的原因是因为您作为字符串传入的过滤器首先需要被解析,然后它被转换为表达式树(不是表达式树的 LINQ 版本)和表达式evaluator 然后充当解释器。您的 LINQ 版本会生成执行过滤的 CIL 代码,这些代码将在运行时转换为本机代码。无需翻译。

您可以通过使用DataRowCollection.Find获得主键的好处:

var rows = lst.Select(key => dtsrc.Rows.Find(key)).Where(row => row != null).ToList();

如果lst 可能包含重复键,您需要先将其删除。您可以使用Enumerable.Distinct() 方法,也可以从一开始就使用HashSet<int>(如果您不关心行的顺序)。

(我之前声称无法优化 Select 方法,因为没有以任何方法可以使用的方式保存主键信息,但我错了,正如我现在的示例所示.)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 2019-03-23
    • 2022-08-22
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多