Answered by:
Inline change tracking performance issues

Question
-
I currently have a highly customized synchronization solution which uses MSF. The general architecture of the solution is that data is synchronized between 2 sites via a web service. The sites have different db schema, so everything is sync'd at an object level. NHibernate is used for data access and change tracking is done inline when a change is made to the business objects right before the object change is flushed to the database.
Inline change tracking like this is very reliable and has no latency, however, the performance seriously decreases when large batches of updates are performed. I have found that the bottleneck is when I increment the tick count, which requires an atomic operation to read the value then increment it. The inline change tracking takes 10-15x as long, which isn't a big deal when a user is just changing a few records, but when there is a bulk change with thousands of records, it is really noticeable.
I tried using the SQL Server Service Broker to asynchronously queue the changes so the tracking doesn't block the application, but this scenario offered no net gains in performance since the Service Broker writes the message to an internal queue table before it processes it.
I am trying to stay away from table level tracking, as the synchronization is done at the business object level. Additionally, I suspect that using SQL Server Change Tracking has a similar performance overhead.
Has anyone had a similar performance issue with change tracking? I would greatly appreciate any thoughts or feedback about my dilemma.
Here is the T-SQL that I have found to be the bottleneck. It doesn't seem to be anything remarkable, but if you loop this 5000 times you will see that the time adds up fast.
BEGIN TRANSACTION
BEGIN TRY--@ReplicaID is uniqueidentifier passed in from the client
DECLARE @NewTickCount bigintSELECT @NewTickCount = TickCount
FROM SynchronizationFMServerReplicas
WHERE ReplicaID = @ReplicaIDSET @NewTickCount = @NewTickCount + 1
UPDATE SynchronizationReplicas
SET TickCount = @NewTickCount
WHERE ReplicaID = @ReplicaID
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION
END CATCHIF @@TRANCOUNT > 0 COMMIT TRANSACTION
Thanks in advance for your thoughts.
Regards,Trevel Beshore
Friday, June 4, 2010 5:51 PM
Answers
-
are you writing your own providers or using the shipping version of database providers ?
sicne you have find the bottleneck is the above code to get new tickcount, any reason you didn't want to use the build in timestamp for it ?
thanks
Yunwen
This posting is provided "AS IS" with no warranties, and confers no rights.- Proposed as answer by jigu2014Microsoft employee, Editor Tuesday, June 15, 2010 5:00 PM
- Marked as answer by jigu2014Microsoft employee, Editor Thursday, June 17, 2010 5:58 PM
Friday, June 11, 2010 7:43 PM
All replies
-
are you writing your own providers or using the shipping version of database providers ?
sicne you have find the bottleneck is the above code to get new tickcount, any reason you didn't want to use the build in timestamp for it ?
thanks
Yunwen
This posting is provided "AS IS" with no warranties, and confers no rights.- Proposed as answer by jigu2014Microsoft employee, Editor Tuesday, June 15, 2010 5:00 PM
- Marked as answer by jigu2014Microsoft employee, Editor Thursday, June 17, 2010 5:58 PM
Friday, June 11, 2010 7:43 PM -
Hi Yunwen,
Thanks for the reply. I have written my own providers. The reason I don't use the timestamp in SQL Server is because I am doing the sync with business objects not tables. All of my logic is for a business object, which may involve many tables, and I don't want to track changes at the table level. The reason I don't use SQL Server Replication is the solution must support the Express version. I am not using SQL Server Change Tracking for both of the aforementioned reasons.
My new plan is to increment the tickcount once for each NHibernate transaction, which may have thousands of changes within it. So instead of having to atomically increment the tickcount which adds a good .5 seconds to the operation for every change, I can make bulk operations much faster by grouping the changes into 1 tickcount. This should be much faster, I just haven't had a chance to work put it all together.
Thanks again.
Trevel
Monday, June 14, 2010 10:02 PM