14

我有一个包含约 60,000 行的数据库表(在 SQL Server 2012 Express 上运行)。

我正在使用以下代码清除旧行:

//Deleting CPU measurements older than (oldestAllowedTime)
var allCpuMeasurementsQuery = from curr in msdc.CpuMeasurements where 
    curr.Timestamp < oldestAllowedTime select curr;
foreach (var cpuMeasurement in allCpuMeasurementsQuery)
{
  msdc.CpuMeasurements.Remove(cpuMeasurement);
}

当删除的行数很大时(大约 90% 或更多的表中的记录正在被删除),操作需要非常长的时间。在比较强大的机器(Intel I5 台式机)上完成这个操作大约需要 30 分钟。

  1. 这看起来像正常行为吗?

  2. 关于我可以做些什么来减少手术时间的任何想法?

谢谢,

4

4 回答 4

19

实体框架不太擅长处理这样的批量操作。在这种情况下,您应该使用ExecuteStoreCommand直接针对数据源执行 SQL。

var deleteOld = "DELETE FROM CpuMeasurements WHERE curr.Timestamp < {0}";
msdc.ExecuteStoreCommand(deleteOld, oldestAllowedTime);

通过这样做,您不需要将实体加载到内存中(只是为了删除它们)并向数据库发出数千个删除命令。

于 2013-05-08T13:51:48.010 回答
13

您应该查看EntityFramework.Extended它是为了帮助批量删除和更新而创建的。

使用它,您可以简单地执行以下操作:

msdc.CpuMeasurements.Delete(curr => curr.Timestamp < oldestAllowedTime);
于 2013-05-08T13:48:02.077 回答
5

这样做的原因是您为每条记录执行数据库更新。您需要进行批量更新。

EntityFramework.extended可以处理这种情况。

于 2013-05-08T13:48:48.983 回答
-1

删除大量数据可能需要很长时间。

您可能必须将 sql 从应用程序中移出并通过SQL Server Agent作为单个 sql 脚本运行。例如,它可以在最安静的时期每天运行一次。

于 2013-05-08T13:48:13.510 回答