1

我有 2 个 SQL Server 数据库,托管在两个不同的服务器上。我需要从第一个数据库中提取数据。这将是一个整数列表。然后我需要将此列表与第二个数据库中多个表中的数据进行比较。根据某些情况,我需要在第二个数据库中更新或插入一些记录。

我的解决方案:(使用 LINQ to Entities 的 WCF 服务/实体框架)

  1. 从 1st db 获取整数列表,不到一秒就得到 20,942 条记录
  2. 我使用以下查询使用整数列表与第二个数据库中的表进行比较:

    List<int> pastDueAccts; //Assuming this is the list from Step#1
    var matchedAccts = from acct in context.AmAccounts
                       where pastDueAccts.Contains(acct.ARNumber)
                       select acct;

上面的查询花费了很长时间,以至于它给出了超时错误。即使 AmAccount 表只有约 400 条记录。

  1. 获得这些matchedAccts 后,我需要在第二个数据库的单独表中更新或插入记录。

有人可以帮助我,我怎样才能更有效地执行第 2 步?我认为 Contains 功能使它变慢。我也尝试了蛮力,通过放置一个 foreach 循环,我一次提取一条记录并进行比较。仍然需要太长时间并给出超时错误。数据库服务器显示只有 30% 的内存已被使用。

4

2 回答 2

0

使用 SQL Profiler 分析发送到数据库的 sql 查询。捕获发送到数据库的 SQL 语句并在 SSMS 中运行。此时,您应该能够捕捉到 Entity Framework 带来的开销。您可以将第 2 步中发出的 SQL 语句粘贴到您的问题中吗?

于 2013-05-08T00:24:12.790 回答
0

查询本身将包含所有 20,942 个整数。

如果你的AmAccount表总是有少量这样的记录,你可以只返回整个ARNumbers 列表,将它们与列表进行比较,然后具体说明要返回哪些记录:

List<int> pastDueAccts; //Assuming this is the list from Step#1
List<int> amAcctNumbers = from acct in context.AmAccounts
                          select acct.ARNumber

//Get a list of integers that are in both lists
var pastDueAmAcctNumbers = pastDueAccts.Intersect(amAcctNumbers);

var pastDueAmAccts = from acct in context.AmAccounts
                     where pastDueAmAcctNumbers.Contains(acct.ARNumber)
                     select acct;

您仍然需要担心为该查询提供了多少个 id,并且最终可能需要批量检索它们。

更新

希望有人有比这更好的答案,但是有这么多记录并且纯粹在 EF 中执行此操作,您可以尝试像我之前所说的那样对它进行批处理:

//Suggest disabling auto detect changes
//Otherwise you will probably have some serious memory issues
//With 2MM+ records
context.Configuration.AutoDetectChangesEnabled = false;

List<int> pastDueAccts; //Assuming this is the list from Step#1

const int batchSize = 100;

for (int i = 0; i < pastDueAccts.Count; i += batchSize)
{
    var batch = pastDueAccts.GetRange(i, batchSize);

    var pastDueAmAccts = from acct in context.AmAccounts
                         where batch.Contains(acct.ARNumber)
                         select acct;
}
于 2013-05-08T00:47:04.960 回答