SQL更新工作不插入

时间:2011-04-26 15:15:06

标签: sql sql-server-2005 tsql

好的,我会尽力描述这一点。我有一个SP,它传递XML并更新并插入另一个表。这在昨天工作。我今天改变的是使用OPENXML vs xml.nodes加载临时表。我甚至改回来了,我仍然得到这个有趣的问题。我有一个更新并插入同一个事务中。更新工作,然后插入挂起,没有错误没有任何...进行9分钟。通常需要10秒钟。根据{{​​1}}禁止阻止流程。有趣的是,Select的Insert不返回任何行,因为它们已经存在于数据库中。更新更新了

中的72438
master.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行。

2 个答案:

答案 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

我认为你应该发布完整的存储过程,因为问题看起来不像你认为的那样。