我有2个SQL Server数据库,托管在两个不同的服务器上。我需要从第一个数据库中提取数据。这将是一个整数列表。然后我需要将此列表与第二个数据库中多个表中的数据进行比较。根据某些条件,我需要在第二个数据库中更新或插入一些记录。
我的解决方案: (使用LINQ to Entities的WCF服务/实体框架)
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条记录。
有人可以帮助我,我怎样才能更有效地完成第二步?我认为Contains函数使它变慢。我也试过暴力,通过一个foreach循环,我一次提取一个记录并进行比较。仍然需要太长时间并给出超时错误。数据库服务器仅显示已使用的内存的30%。
答案 0 :(得分:0)
使用SQL事件探查器配置发送到数据库的sql查询。捕获发送到数据库的SQL语句并在SSMS中运行它。您应该能够捕获Entity Framework强加的开销。你可以在你的问题中粘贴步骤#2中发出的SQL语句吗?
答案 1 :(得分:0)
查询本身将包含所有20,942个整数。
如果你的AmAccount
表总是有这么多的记录,你可以只返回ARNumber
的整个列表,将它们与列表进行比较,然后具体说明哪些记录到返回:
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;
}