views:

189

answers:

2

Hi, the code below works fine but it takes an absolute age to run. How can I speed this up?

Background: I have linked my local server to my remote server. From my local server, I need to insert data from the remote server into my local server and then update the table on my remote server. See snippet for the exact details.

DECLARE @temp1 TABLE
(LoginID INT PRIMARY KEY, 
UserID UNIQUEIDENTIFIER, 
Message NCHAR(1000))

INSERT INTO [My Local Server].[DB Name].dbo.Login 
(LoginID, UserID, Message)
OUTPUT INSERTED.LoginID, INSERTED.UserID, INSERTED.Message INTO @temp1
SELECT LoginID, UserID, Message
FROM [Remote Server].[Remote DB Name].dbo.Login2 
WHERE Date IS NULL

UPDATE [Remote Server].[Remote DB Name].dbo.Login2 
SET Date = GETDATE()
FROM [Remote Server].[Remote DB Name].dbo.Login2 AS z
WHERE EXISTS (SELECT 1 FROM @temp1 AS x WHERE z.Date IS NULL AND x.LoginID = z.LoginID)

EDIT:

In addition, is there anyway I can compress/zip the data being sent back and forth?

+2  A: 

Is the INSERT or the UPDATE the culprit, or are they both bad?

You're bringing the rows with NULL values for Date from the remote server, and then sending those values back again in the UPDATE statement. You could potentially save traffic by selecting the updated rows and inserting them locally. It looks like you could do this (sorry, no MS SQL Server available to test against) by saying

INSERT INTO [My Local Server].[DB Name].dbo.Login 
(LoginID, UserID, Message)
SELECT *
FROM
  UPDATE [Remote Server].[Remote DB Name].dbo.Login2 
  SET Date = GETDATE()
  OUTPUT LoginID, UserID, Message
  WHERE Date IS NULL

See the MSDN INSERT docs and OUTPUT docs for details.

Or maybe OUTPUT INTO is the way to go:

UPDATE [Remote Server].[Remote DB Name].dbo.Login2 
SET Date = GETDATE()
OUTPUT LoginID, UserID, Message
INTO [My Local Server].[DB Name].dbo.Login (LoginID, UserID, Message)
WHERE Date IS NULL
Harold L
Sorry, forgot to mention this. The INSERT is bearable. Its the update thats slow. You're right, I'm looking to reduce the traffic. Unfortunately I cant test your script as I'm just stepping out for the office now. But thanks for your contribution. I will try it tomorrow and post my results.
Nai
You originally pull rows where Date IS NULL from the remote server, but then you UPDATE the Date column for rows where DateCollected IS NULL. That means you might insert a different set of rows locally than you update. Is that on purpose?
Harold L
OH dear, DateCollected was a typo on my part. It should be date. So to answer your question, it's the same set of data I am INSERTING and UPDATING
Nai
Using your script, Im getting the following error msg:Incorrect syntax near the keyword 'UPDATE'.
Nai
Looks like the SET clause should come before the OUTPUT clause. Also, I added a 2nd query: using OUTPUT INTO to send the updated rows directly into the local table.
Harold L
A: 

Seems that the UPDATE has to pull the entire remote table over, scan the records and do a nested look up into the @temp1, the ship back the updates. Its just a guess, w/o more additional information. You should look at the actual execution plan and trace where is the time spent. Also using STATISTICS IO ON could help.

This is really just a shot in the dark, but maybe you can try a join instead of the EXISTS:

WITH cte_remote AS (
  SELECT z.Date
    FROM [Remote Server].[Remote DB Name].dbo.Login2 AS z
    JOIN @temp1 AS x ON z.DateCollected IS NULL AND x.LoginID = z.LoginID)
UPDATE cte_remote 
    SET Date = GETDATE();
Remus Rusanu
Well I have kinda bypassed the problem. I am not executing remote SP's that updates my remote table rather than using distributed queries. MUCH MUCH more efficient. Thanks for your suggestion anyway!
Nai