【问题标题】:Enumerating large data sets multiple times using LINQ to Entities使用 LINQ to Entities 多次枚举大型数据集
【发布时间】:2014-01-10 20:14:00
【问题描述】:

假设我的 SQL 数据库中有两个表。 1. 一个包含数千条记录的中型表,称为 MyTable1 2. 一个拥有数百万条记录(并且每天都在增长)的大表,名为 MyTable2

MyTable1 和 MyTable2 都有一个叫做 Hash 的属性,可以相等。

我正在寻找最有效的方法来使用 Linq to Entities 来遍历 MyTable1 并在 MyTable2 中找到所有具有相同哈希的记录并保存到另一个表中。这是代码外观的简化视图。

using(var db = new context()) {
    var myTable1Records = db.MyTable1.Select(x => x);

    foreach(var record in myTable1Records) {  
        var matches = db.MyTable2.Where(y => y.Hash.Equals(record.Hash)).Select(y => y);
        foreach(var match in matches) {
           // Add match to another table
        }
    }
}

我发现随着 MyTable2 的大小每天都在变大,这段代码的性能显着下降。我正在尝试有效处理此类场景的一些想法是:

  1. 在 db.MyTable2 上设置 MergeOption.NoTracking,因为它纯粹是一个读取操作。不幸的是,没有看到这方面的太大改善。
  2. 使用 .ToList() 将 MyTable2 拉入内存以消除对 db 的多次调用
  3. 创建代码可以迭代的 MyTable2 的“块”,因此它不会每次都查询完整的百万以上记录。

我很想看看您是否发现其他技术或灵丹妙药在这种情况下有效。谢谢!

【问题讨论】:

  • 您在数据库中的哈希列上有索引吗?
  • 您是否必须为 c# 带来数百万个值才能执行 RDMS 可以非常有效地执行的操作?
  • 这可能有点偏离使用 Linq 的主题,但是如何在数据库中创建一个视图,其中这 2 个表基于 Hash 字段连接,然后只查询连接的表? - 让您的数据库为您完成这部分的工作......这就是它经过优化后要做的事情!

标签: c# sql linq entity-framework


【解决方案1】:

您有一个名为Hash 的属性。将其用作哈希!将第一个表存储在Hash 键入的Dictionary 中,然后遍历第二个表检查Dictionary 中的匹配项,再次键入Hash

或者,更好的是,使用 LINQ:

var matches = db.MyTable1.Intersect(db.MyTable2);

如果您需要进行自定义比较,请创建IEqualityComparer。 (我假设您正在进行某种类型的投影,并且 Select(x => x) 是本问题的占位符。)

或者,更好的是,这个操作完全在数据库中的存储过程或视图中进行可能会更好。你实际上是在做一个JOIN,但使用 C# 来做。您承担了从数据库到客户端应用程序的往返时间成本,因为这可能全部都在数据库服务器上完成。

【讨论】:

    【解决方案2】:

    您在这里所做的是执行内部连接。通过使用查询提供程序,您甚至可以确保这项工作在数据库端完成,而不是在应用程序的内存中完成;你只会拉下匹配的结果,没有更多:

    var query = from first in db.MyTable1
        join second in db.MyTable2
        on first.Hash equals second.Hash
        select second;
    

    【讨论】:

      【解决方案3】:

      【讨论】:

        【解决方案4】:

        索引您的哈希列可能会有所帮助。假设 Hash 为 char 或 varchar 类型,则索引可支持的最大长度为 900 字节。

        CREATE NONCLUSTERED INDEX IX_MyTable2_Hash ON dbo.MyTable2(Hash);
        

        关于索引 varchar 的性能,您可能需要查看此处 SQL indexing on varchar

        【讨论】:

          猜你喜欢
          • 2011-08-03
          • 1970-01-01
          • 1970-01-01
          • 2013-03-13
          • 2017-11-18
          • 1970-01-01
          • 1970-01-01
          • 2013-09-29
          • 2010-10-29
          相关资源
          最近更新 更多