Question

As the documentation says, rowversion data type is auto-updated every time a row is updated using a global auto-incremented number within the entire database scope.

My question is the following: Say I have 10000 concurrent updates on tables that have a rowversion column. Since all try to access and update atomically that global number, I'd imagine that all of them are processed in a 'serial' way which may reduce performance compared to tables that doesn't need to access that number.

Is this correct?.

Was it helpful?

Solution

I'd imagine that all of them are processed in a 'serial' way which may reduce performance compared to tables that doesn't need to access that number.

In theory, yes. In practice, you would have to measure the effect to know if it is important.

The current rowversion value is cached in memory and atomically updated using a cmpxchg instruction (in DBTABLE::GetNewDbTimestamp). Any collisions due to multiple sessions requesting a new rowversion value concurrently are handled by a spinlock (type DBTABLE in sys.dm_os_spinlock_stats). Monitoring backoffs and sleeps in that DMV is probably the first step to see if it might be causing a problem.

Compared with the extensive work needed to actually insert or update a row, maintaining the timestamp value is probably pretty trivial. The only way to really be sure though would be to test it on a suitable workload inserting or updating many tables with rowversion columns concurrently.

As a quick test, I ran two sessions inserting 500,000 rows with a single integer value into a table variable with a rowversion column. The batch was repeated 100 times on each connection for a total of 50,000,000 inserts each.

SET NOCOUNT ON;
DECLARE @T AS table (i integer, rv rowversion);
INSERT @T (i) SELECT N.n FROM dbo.Numbers AS N WHERE N.n BETWEEN 1 AND 500000;
GO 100

Typical results were that execution took 45 seconds with:

Spinlocks

With a binary(8) column default 0x, the same test runs for 15 seconds.

So there is definitely a cost associated with rowversion. I do doubt this would often be a major cause of problems though. Maybe if a large number of tables has rowversion columns and were all being inserted/updated at a high rate concurrently.

I suppose if natively compiled memory optimized tables ever support rowversion, we might get closer to the time when this becomes a real bottleneck with non-durable tables, but maybe not even then. Identity and sequences use a similar mechanism, and I have not heard any reports about that becoming a problem specifically.

Some related reading:

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top