【发布时间】:2015-04-01 10:27:19
【问题描述】:
我有一个大表(7000 万条记录),它也被大量索引(5 个索引),我需要与它合并大约 100000 条记录(连续几次)。所以我做了合并,一些合并是好的,一些返回
SQL Server 数据库引擎的实例此时无法获取 LOCK 资源。当活动用户较少时重新运行您的语句。请数据库管理员检查此实例的锁和内存配置,或检查长时间运行的事务。
合并没有围绕它的事务,并且从实体框架(v 4.0)调用(作为存储过程)也没有任何事务。
using (var b = new MyEntities())
{
b.CommandTimeout = 36000;
b.Merge_My_Stuff();
}
服务器还有 16 Gb 的 RAM(大部分由 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 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
【问题讨论】:
-
请添加实际的合并语句,最好是它的执行计划
-
尝试做多个小批量,而不是一次 100K。
-
我们来做一个实验。将
WITH(TABLOCKX)应用于该语句中涉及的所有表。错误应该消失了。这说明这个语句生成的锁的数量是问题,和我怀疑的一样。 -
technet.microsoft.com/en-us/library/ms184286(v=sql.105).aspx 浏览锁升级的场景和要求列表。有什么可以阻止它的吗?由于某种原因,查询似乎每行目标占用一个锁。 100k 锁不算什么。该错误可能来自尝试使用 70m 锁。
-
P.S.您对
IsNull()的使用会停止使用这些列上的任何索引的优化器。
标签: sql-server