好的,我会尽力描述这一点。我有一个SP,它传递XML并更新并插入另一个表。这在昨天工作。我今天改变的是使用OPENXML vs xml.nodes加载临时表。我甚至改回来了,我仍然得到这个有趣的问题。我有一个更新并插入同一个事务中。更新工作,然后插入挂起,没有错误没有任何...进行9分钟。通常需要10秒钟。根据{{1}}禁止阻止流程。有趣的是,Select的Insert不返回任何行,因为它们已经存在于数据库中。更新更新了
中的72438master.sys.sysprocesses
我不知道可能导致我的问题的原因是什么?权限我不这么认为?空间我不这么认为,因为会返回错误吗?
查询:
SQL Server Execution Times:
CPU time = 1359 ms, elapsed time = 7955 ms.
ROWS AFFECTED(72438)
和
UPDATE [Sales].[dbo].[WeeklySummary]
SET [CountryId] = I.CountryId
,[CurrencyId] = I.CurrencyId
,[WeeklySummaryType] = @WeeklySummaryTypeId
,[WeeklyBalanceAmt] = M.WeeklyBalanceAmt + I.WeeklyBalanceAmt
,[CurrencyFactor] = I.CurrencyFactor
,[Comment] = I.Comment
,[UserStamp] = I.UserStamp
,[DateTimeStamp] = I.DateTimeStamp
FROM
[Sales].[dbo].[WeeklySummary] M
INNER JOIN
@WeeklySummaryInserts I
ON M.EntityId = I.EntityId
AND M.EntityType = I.EntityType
AND M.WeekEndingDate = I.WeekEndingDate
AND M.BalanceId = I.BalanceId
AND M.ItemType = I.ItemType
AND M.AccountType = I.AccountType
更新
尝试这里的建议有一段时间我在我的存储过程调用
之前运行以下命令INSERT INTO [Sales].[dbo].[WeeklySummary]
([EntityId]
,[EntityType]
,[WeekEndingDate]
,[BalanceId]
,[CountryId]
,[CurrencyId]
,[WeeklySummaryType]
,[ItemType]
,[AccountType]
,[WeeklyBalanceAmt]
,[CurrencyFactor]
,[Comment]
,[UserStamp]
,[DateTimeStamp])
SELECT
I.[EntityId]
, I.[EntityType]
, I.[WeekEndingDate]
, I.[BalanceId]
, I.[CountryId]
, I.[CurrencyId]
, @WeeklySummaryTypeId
, I.[ItemType]
, I.[AccountType]
, I.[WeeklyBalanceAmt]
, I.[CurrencyFactor]
, I.[Comment]
, I.[UserStamp]
, I.[DateTimeStamp]
FROM
@WeeklySummaryInserts I
LEFT OUTER JOIN
[Sales].[dbo].[WeeklySummary] M
ON I.EntityId = M.EntityId
AND I.EntityType = M.EntityType
AND I.WeekEndingDate = M.WeekEndingDate
AND I.BalanceId = M.BalanceId
AND I.ItemType = M.ItemType
AND I.AccountType = M.AccountType
WHERE M.WeeklySummaryId IS NULL
仍在插入语句停止,再次插入0行。
答案 0 :(得分:2)
实际上只有一些事情可以进行,这里的诀窍是按顺序排除它们,从最简单到最复杂。
步骤1:手工制作一组要运行的XML,它将只生成一个插入而没有更新,因此您可以按原样“回到基础”,并确定代码仍在按预期执行,并且结果正是你所期望的。这可能看似愚蠢或不必要,但你真的需要这个现实检查才能开始。
第2步:手工制作一组XML,它将生成一组中等大小的插入,仍然没有更新。根据您对日常工作的经验,尝试找到能在3-4秒内运行的东西。也许5000行。它是否继续按预期运行?
步骤3:假设步骤1和2很容易通过,下一个最可能的问题是TRANSACTION SIZE。如果您的更新在单个语句中达到74,000行,则SQL Server必须分配资源,以便在中止的情况下回滚所有74,000行。通常,您应该假设维护事务所需的资源(和时间)随着行数的增加而呈指数级爆炸。因此,手工制作一组包含50,000行的插入物。你会发现它需要更多的时间。让它完成。是10分钟,一小时?如果它需要很长时间但是完成,那么TRANSACTION SIZE就会出现问题,服务器正在窒息,试图跟踪在发生故障时回滚插件所需的所有内容。
步骤4:确定整个存储过程是否在单个隐含事务中运行。如果是这样,事情就更糟了,因为SQL Server正在跟踪回滚所有74,000个更新和???插入单个事务中。见本页:
http://msdn.microsoft.com/en-us/library/ms687099(v=vs.85).aspx
步骤5:如果您有一个隐式事务,您可以。 A)关闭它,这可能有助于一些但不会完全解决问题,或者B)将sproc分成两个单独的调用,一个用于更新,一个用于插入,因此至少两个在单独的事务中。
第6步:考虑“分块”。这是一种避免爆炸性交易成本的技术。只考虑INSERT让我们开始,你将insert插入一个循环,开始并在每次迭代中提交一个事务,并在受影响的行为零时退出。 INSERT被修改,以便您只从源中拉出前1000行并插入它们(1000个数字是任意的,您可能会发现5000会产生更好的性能,您必须进行一些实验)。一旦INSERT影响零行,就不再需要处理行并且循环退出。
快速编辑:“分块”系统有效,因为大量行的完整吞吐量看起来像二次方。如果执行影响大量行的INSERT,则所有行的总处理时间将会爆炸。另一方面,如果你将它分解并逐行,那么打开和提交每个语句的开销会导致所有行的总时间爆炸。在中间的某个地方,当你在每个语句中“分块”出1k行时,事务要求是最小的,打开和提交语句的开销可以忽略不计,并且所有行的总处理时间是最小的
答案 1 :(得分:0)
我遇到了一个问题,即存储的proc实际上是在运行过程中重新编译的,因为它正在从临时表中删除行。我的情况看起来不像你的情况,但我的情况太奇怪了,阅读它可能会给你一些想法。
Unexplained SQL Server Timeouts and Intermittent Blocking
我认为你应该发布完整的存储过程,因为问题看起来不像你认为的那样。