2015-04-01 1399 views
0

我有大表(7000万条记录),这也是索引严重(5个索引),我需要与它合并大约100 000条记录(几个连续数次)。所以我做了合并和一些合并是好的,并且有些返回SQL Server数据库引擎的实例目前无法获得LOCK资源

此时SQL Server数据库引擎的实例无法获得LOCK资源。在活动用户较少时重新运行您的声明。请数据库管理员检查此实例的锁定和内存配置,或检查长时间运行的事务。

合并中没有任何事务,并且从实体框架(v 4.0)中调用(作为存储过程)也没有任何事务。

using (var b = new MyEntities()) 
{ 
    b.CommandTimeout = 36000; 
    b.Merge_My_Stuff(); 
} 

此外服务器具有的RAM 16 GB(其中大部分是采取由SQL Server),在该表中的数据是2.5 Gb和索引7 GB。 我查看了内存限制,他们是

max server memory (MB) 2147483647 2147483647 Maximum size of server memory (MB) 
min server memory (MB) 0 16 Minimum size of server memory (MB) 

任何意见,将不胜感激。此外,为什么SQL Server需要这么多的锁进行合并?

编辑 MERGE语句是(执行计划,我会在以后添加)

merge Target_table as target 
using (select * from I_Tmp) as source 
on target.A_ID = source.A_ID and 
    target.B_ID = source.B_ID and 
    isnull(target.C_ID, 0) = isnull(source.C_ID, 0) 
when not matched by target then 
    insert(A_ID, B_ID, C_ID, D, E) 
    values(source.A_ID, source.B_ID, source.C_ID, D, E) 
when matched then 
    update 
    set D= source.D, 
     E= source.E; 

delete from I_Tmp 
+1

请添加实际的合并声明并理想地执行它的执行计划 – 2015-04-01 10:57:36

+1

尝试一次执行多个较小的批次,而不是100K。 – gvee 2015-04-01 11:13:39

+0

看起来锁定升级已禁用。为什么SQL Server需要上百万个锁?检查表选项和跟踪标志。 SQL Server完全可以在一个语句中编写7千万行。完全没有麻烦。 – usr 2015-04-01 11:50:00

回答

1

看起来像一个锁定超时错误。它可能与服务器内存无关,而是由与其他线程的争用引起的。

这里有一对夫妇的事情,可能会帮助:

  1. 确保索引所有的合并条件(A_ID,B_ID,C_ID)作为键(甚至更好的存在,如果你的聚集索引这些作为其键)
  2. 减少批量大小显著

如果无法降低批量大小,可以考虑使用TABLOCK/TABLOCKX提示您的MERGE语句。由于批量较大,无论如何,SQL可能会将您的锁升级为表锁,从而增加事务处理时间。直接进入表锁可以减轻超时。

+0

与(tablockx)做了诡计 – ren 2015-04-03 15:49:21