sql server语句优化1:去掉循环语句

公司前同事写的一个存储过程,在上生产时数据量少时都没有问题,随着数据量的增大,这个存储过程执行时越来越慢,看了一下,里面用到了大量的嵌套循环,还有嵌套游标。经过对语句的调整,将循环取消,改为结构化批量执行,大大提高运行效率。取自其中一部分代码:

 原代码:

经分析,这段代码中有嵌套循环,

第一层循环:从表中一条条的取数,找到工艺路线

第二层循环:将工艺路线拆分,找到上下工艺后,插入到明细表中

select @DataTableCount=count(*) from #DataTable
if(@DataTableCount>0)
begin
	set @i=1
	while(@i<@DataTableCount+1)
	begin
		select @OrderId=OrderId,@Upi=ProductionDetailExtendEntity_Id,@Routing=Routing,@Barcode=Barcode,@Partposstr=Partposstr from #DataTable where IID=@i

		select @Routing = Routing,@OrderEntity_Id= h.Id,@ProductionDetailExtendEntity_Id = f.Id,
		@OrderId = h.OrderId,@ProductionBatchEntity_Id=a.Id,@Planno=a.PlanNo 
		from T_ProductionBatch a left join T_ProductionBatchDetail b on a.Id=b.ProductionBatchEntity_Id
		left join T_ProductionSolutionOrder c on c.Id=b.Id 
		left join T_BOM_Order h on c.OrderEntity_Id=h.Id
		left join T_BOM_ItemDetail d on c.Id=d.ProductionSolutionOrder_Id 
		left join T_BOM_ItemDetailExtend f on d.Id=f.ProductDetail_Id 
		where f.Id=@Upi

		if object_id('tempdb..#dtOP') Is Not Null
		drop table #dtOP 
        select id=identity(int,1,1),col into #dtOP 
		from dbo.f_SplitStr(@Routing,'_') a inner join T_Operation b on a.col=b.OPCode where b.IsNoWorkOrder=0 
		select @OperationContu=count(*) from #dtOP
		set @j=1
		while(@j<@OperationContu+1)
		begin
			set @LastOPCode=''
			set @NextOPCode=''
			select @OPCode=col from #dtOP where id=@j
			select @LastOPCode=col from #dtOP where id=@j-1
			select @NextOPCode=col from #dtOP where id=@j+1
			select @SequenceNo=Sequence from T_Operation where OPCode=@OPCode
			insert into #T_WorkOrderDetail(OPCode,OrderId,OrderEntity_Id,ProductionDetailExtendEntity_Id,ProductionBatchEntity_Id,SequenceNo,LastOPCode,NextOPCode,Partposstr,Barcode)
			values(@OPCode,@OrderId,@OrderEntity_Id,@ProductionDetailExtendEntity_Id,@ProductionBatchEntity_Id,@SequenceNo,@LastOPCode,@NextOPCode,@Partposstr,@Barcode)

			set @j=@j+1
		end
		set @i=@i+1	 
	end
end   

优化后的代码:

批量找到工艺表

批量插入到明细表中


select @DataTableCount=count(*) from #DataTable
if(@DataTableCount>0)
begin
	insert into  #dtOP(iid ,id,col ,creatdate)
	select a.IID,ROW_NUMBER() over(partition by a.iid order by a.iid) id,b.col,getdate()
	from #DataTable  a
	cross apply dbo.f_SplitStr(a.Routing,'_') b
	order by iid asc 
	--批量插入,取消循环操作
	insert into #T_WorkOrderDetail(OPCode,OrderId,OrderEntity_Id,ProductionDetailExtendEntity_Id,ProductionBatchEntity_Id,SequenceNo,LastOPCode,NextOPCode,Barcode,Partposstr,
									orderstatus , OrderInfo1,OrderInfo2,OrderInfo3,OrderInfo4,OrderInfo5,CreatedTime,
									Colour1,price1,price2,Price3, packageQtys,
									ProductionSolutionEntity_Id,Planno,fleng,fwidth,ProcessingCnt,EdgeLength)
	select b.col OPCode ,a.OrderId,a.OrderEntity_Id, a.ProductionDetailExtendEntity_Id ,a.ProductionBatchEntity_Id, e.Sequence SequenceNo, isnull(c.col,'') LastOPCode ,  isnull(d.col,'') NextOPCode  , a.Barcode , a.Partposstr,
			a.orderstatus ,a.OrderInfo1,a.OrderInfo2,a.OrderInfo3,a.OrderInfo4,a.OrderInfo5,a.CreatedTime,
			a.Colour1,a.price1,a.price2,a.Price3, a.packageQtys,
			a.ProductionSolutionEntity_Id,a.PlanNo,a.fleng,a.fwidth,a.ProcessingCnt,a.EdgeLength
	from #DataTable a 
	inner join  #dtOP b on a.iid = b.iid
	left join	#dtOP c on b.iid = c.iid and b.id -1 = c.id   --上个工序
	left join	#dtOP d on b.iid = d.iid and b.id +1 = d.id   --下个工序
	left join	T_Operation e on b.col = e.OPCode
	order by a.iid asc ,b.id asc
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值