SQL insert into suspended - 读取未提交或拆分查询?

时间:2018-06-07 07:51:33

标签: sql sql-server stored-procedures

我有一个包含两个插入查询的存储过程。在运行sp时我经常看到这两个被挂起。 sp已经在几乎没有流量的测试服务器上进行了测试,但现在当我们将它移动到生产服务器上时,这些暂停状态出现了1-2个死锁。

我认为SQL Server在运行这些查询时会创建表锁,但我不知道解决此问题的首选方法是什么? 插入查询会在一次迭代中将30000条记录移动到另一个数据库中。这些是归档数据,因此来自正常生产过程的查询与归档的数据无关,它们已有2 - 3年的历史。

  • 我可以在选择中添加WITH NOLOCK以避免挂起状态和死锁吗?
  • 或者我应该将ISOLATION LEVEL设置为READ UNCOMMITTED? (这些记录很旧,他们不会改变)
  • 我还有其他选择吗?游标必须逐个存档才能运行? (我试着直到现在才使用游标。)

这是两个查询。 @workitemids和@workstepids是包含一个int字段的表变量。

insert into archive_****.archive.workitems
            select * from ****.dbo.WorkItems where ****.dbo.workitems.Id in (select Id from @workitemIds);

insert into archive_****.archive.worksteps([Id], [Timestamp], [Description], [WorkPlace_Id], [WorkItemState_Id], [UserId], [WorkItem_Id], [Technology_Id], [Failcodes_Id], [DrawingNo], [ManualData], [Deleted], [WorkItemState_Arrival_Id], Workstepdatas)
            select [Id], [Timestamp], [Description], [WorkPlace_Id], [WorkItemState_Id], [UserId], [WorkItem_Id], [Technology_Id], [Failcodes_Id], [DrawingNo], [ManualData], [Deleted], [WorkItemState_Arrival_Id],
                (select Fieldname Field, Value [Value], Unit [Unit] from ****.dbo.workstepdatas wsd
                    left join ****.dbo.technologydatafields tdf on tdf.Id = wsd.TechnologyDatafields_Id
                    where tdf.fieldname is not null and wsd.WorkStep_Id = ws.Id
                        and value NOT LIKE '%[' + CHAR(0)+ '-' +CHAR(31)+']%'  COLLATE Latin1_General_100_BIN2
                    for xml auto,type)
            from ****.dbo.worksteps ws
            where ws.Id in (select Id from @workstepIds);

1 个答案:

答案 0 :(得分:1)

请尝试将嵌套查询写入cte,如下所示,并告知是否有任何进展。您需要更改数据库名称。

insert into archive_db.archive.workitems (with tablock)
select *
from db.dbo.WorkItems as w
inner join @workitemIds as wi
    on w.Id = wi.id;

with xmlcte
    (ID, xmlRow)
as (
       select ws.id
            , (
                  select Fieldname as Field                           
                       , [Value]
                       , Unit
                  from db.dbo.workstepdatas wsd
                  left join db.dbo.technologydatafields tdf
                      on tdf.Id = wsd.TechnologyDatafields_Id
                  where
                      tdf.fieldname is not null
                      and wsd.WorkStep_Id = ws.Id
                      and [value] not like '%[' + char(0) + '-' + char(31) + ']%' collate Latin1_General_100_BIN2
                  for xml auto, type
              ) as xmlRow
       from db.dbo.worksteps as ws
   )
insert into archive_db.archive.worksteps (with tablock)
     (
         [Id]
       , [Timestamp]
       , [Description]
       , [WorkPlace_Id]
       , [WorkItemState_Id]
       , [UserId]
       , [WorkItem_Id]
       , [Technology_Id]
       , [Failcodes_Id]
       , [DrawingNo]
       , [ManualData]
       , [Deleted]
       , [WorkItemState_Arrival_Id]
       , Workstepdatas
     )
select ws.[Id]
     , [Timestamp]
     , [Description]
     , [WorkPlace_Id]
     , [WorkItemState_Id]
     , [UserId]
     , [WorkItem_Id]
     , [Technology_Id]
     , [Failcodes_Id]
     , [DrawingNo]
     , [ManualData]
     , [Deleted]
     , [WorkItemState_Arrival_Id]
     , [xmlRow]
from db.dbo.worksteps ws
inner join @workstepIds as wsi
    on ws.Id = wsi.id
inner join xmlcte -- I assume inner join is OK
    on ws.id = xmlcte.id;