I will try to load the elements into the local variable of the table first before doing the join.
DECLARE @WIP Table ( Item varchar(25), WIP int ) --Get Work In Progress Numbers INSERT INTO @WIP select ( UPC.ItemPrefix + '-' + UPC.ItemCode ) As Item, SUM(PO.Quantity) As WIP --into #WIP from [NCLGS].[dbo].[AL_ItemUPCs] UPC INNER JOIN al_PO PO ON PO.UPCID = UPC.UPCID where PO.status in ( 'Assigned', 'New', 'UnAssigned', 'WaitingForFile' ) Group by ( UPC.ItemPrefix + '-' + UPC.ItemCode ) DECLARE @Item TABLE (ItemNumber INT PRIMARY KEY, QtyOnHand INT) SELECT ItemNumber, QtyOnHand FROM [Server].[Database].[dbo].[Item] --SLOW PART, takes over 17 minutes UPDATE [Server].[Database].[dbo].[Item] SET QtyOnHand = IH.QtyOnHand, QtyWorkInProgress = W.WIP FROM Avanti_InventoryHeader IH INNER JOIN @item I ON I.ItemNumber = IH.ItemNumber LEFT JOIN @WIP W ON IH.ItemNumber = W.Item WHERE isnumeric(left(IH.ItemNumber, 2)) = 0
In addition, you can consider the possibility of further restricting updates by deleting records from a table variable that are not updated, and attach only the updated records to the linked server.
DECLARE @Item TABLE ( ItemNumber INT PRIMARY KEY, QtyOnHand INT, updated BIT DEFAULT ( 0 ), WIP int ) SELECT ItemNumber, QtyOnHand FROM [Server].[Database].[dbo].[Item] UPDATE i SET i.QtyOnHand = ih.QtyOnHand, updated = 1 FROM @item i INNER JOIN Avanti_InventoryHeader IH ON I.ItemNumber = IH.ItemNumber LEFT JOIN @WIP W ON IH.ItemNumber = W.Item WHERE isnumeric(left(IH.ItemNumber, 2)) = 0 DELETE FROM @item WHERE updated = 0 UPDATE I SET QtyOnHand = IH.QtyOnHand, QtyWorkInProgress = IH.WIP FROM [Server].[Database].[dbo].[Item] I INNER JOIN @item IH ON I.ItemNumber = IH.ItemNumber
Jappi source share