June 16, 2005 at 5:41 am
Hi,
Can someone interpit the following behavour for me.
The following scirpt is a modified extract from a longer SP that runs nightly and refreshes a Remote Database via LinkedServers with changes that occurred since the script was last run. I have modified the script to set the Last run date to the currentSystem time as I know no updates have occurred therefore no updates need to be pushed to the remote server. I expected this script to run in seconds yet it takes 10 minutes. The tables in question have 1 million rows and I need to push the data out to the remote servers
declare @LastRunDate datetime
set @LastRunDate = getdate()
UPDATE ProductionDB.Catalog.Dbo.Product
SET Description = remoteProduct.Description,
SequenceNo = remoteProduct.SequenceNo ,
Side = remoteProduct.Side ,
Price = remoteProduct.Price,
UpdatedDate = remoteProduct.UpdatedDate
FROM ProductionDB.Catalog.Dbo.Product remoteProduct
INNER JOIN CentralDB.dbo.Product as ProductMaster
on ProductMaster.ProductID = remoteProduct.ProductID
WHERE ProducTMaster.UpdatedDate > @LastRunDate
Looking at the execution plan I can see that the 1 million rows are returned from the remote server to the central server, sorted and then compared to the rows return from the productmaster table which is zero. I have read that all updates are performed locally so therefore this behaviour is as expected. However here is the weid bit of the 15 tables that I update this way some return all rows and take minutes to execute others return no rows from the remote server and execute in under 1 second. Also if I remove the variable @LastRunDate and replace it with the fn GetDate() as in
WHERE ProducTMaster.UpdatedDate > GetDate(), the query executes in under 1 second as no remote rows are returned. Anyone know why this is ? Why using the variable causes all rows returned and yet getdate() doesnt ? Any help appreciated.
Cheers
A
June 16, 2005 at 6:38 am
It may be parameter sniffing at work. However I think that the simplest workaround would be to do something like this :
IF EXISTS (Select * from dbo.ProducTMaster WHERE ProducTMaster.UpdatedDate > @LastRunDate)
begin
update...
end
June 16, 2005 at 7:38 am
I agree and thats the way I will be implementing it. However it would mean that if 5 rows in the master copy changed then all remote rows are copied over to the local and then the 5 rows are sent back to be updated. I suppose I could insert the rows that have changed into a tmp table on the remote db side and then call a remote sp to update the changes on the remote side and then delete the changes. However I would like to understand why my existing script is behaving as it is.
June 16, 2005 at 7:56 am
Sql server HAS TO import the data for the join. There's no way around that (unless you do as you said and send the new data to the other server and let him do the work.
June 16, 2005 at 9:25 am
I have modified my sp and now i pass in @lastRunDate as a parameter and it works fine. As in the sp now runs in 3 sec where no updates exist compared to 20 before. However If I set the date to 3 days back and get 3 days of updates I get a new error.
Server: Msg 7343, Level 16, State 4, Procedure tester, Line 16
OLE DB provider 'SQLOLEDB' could not UPDATE table '[RemoteDB].[Catalog].[Dbo].[Product]'. The consumer could not delete the row. A deletion is pending or has already been transmitted to the data source.
[OLE/DB provider returned message: Cursor operation conflict]
OLE DB error trace [OLE/DB Provider 'SQLOLEDB' IRowsetChange::SetData returned 0x80040e23: The consumer could not delete the row. A deletion is pending or has already been transmitted to the data source.].
June 16, 2005 at 9:27 am
Never seen that!!
June 16, 2005 at 10:10 pm
That's kind of a kewl error. I don't think I've actually seen it either. What version of MDAC are you on? You might want to consider updating the MDAC if you're on anything earlier than MDAC 2.8.
Let us know what happens with this.
Derrick Leggett
Mean Old DBA
When life gives you a lemon, fire the DBA.
June 17, 2005 at 3:45 am
Are version is MDAC 2.80.1022.0.
No idea whats causing this error. I am stumpted.
June 17, 2005 at 11:06 am
I found this post and low and behold it worked. http://dbforums.com/t507548.html. SET NOCOUNT was set on at server level on both servers. I turned this off at server level re-ran my update and it worked fine. Hopefully my complete script will run smoothly.
June 17, 2005 at 11:16 am
Testing my complete update script and while its working, I now noticed through the profiller that for one table where as before it fetched 100 rows at at time from the remote server it now fetches 1 at a time. aaaaggggh (pulling hair out of head)
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply