HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

Is MAX(rowversion) optimized for the table?

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
therowversionoptimizedmaxfortable

Problem

When trying MAX(rv) for the table--the rv rowversion is defined there--I have noticed that the operation is very fast even for big tables. Is there an index implemented implicitly for the rowversion column? Or is the MAX() function optimized for the rowversion value? In other words, is the maximum value for the rowersion of the table stored elsewhere?

It is SQL Server 2014 if it matters.

Solution

No, it doesn't appear there is any special treatment for rowversion columns. This small demo confirms the entire index is scanned to find the MAX value:

CREATE TABLE dbo.RvTest
(
    Id int NOT NULL,
    rv rowversion,

    CONSTRAINT PK_RvTest PRIMARY KEY (Id)
);
GO

INSERT INTO dbo.RvTest
    (Id)
SELECT DISTINCT 
    [number]
FROM master.dbo.spt_values v1
WHERE 
    v1.[number] IS NOT NULL;
GO

SELECT MAX(rv) FROM dbo.RvTest;


Interactive db<>fiddle link

This makes sense when you consider that the rowversion is unique across the whole database, rather than a specific table:

Each database has a counter that is incremented for each insert or update operation that is performed on a table that contains a rowversion column within the database. This counter is the database rowversion.

It doesn't look like SQL Server stores table-specific metadata about rowversions.

If you need that check to be very fast, there's nothing stopping you from indexing that column yourself:

CREATE NONCLUSTERED INDEX IX_rv ON dbo.RvTest (rv DESC);


Which results in a single row being read for that MAX query:

As a side note, as Panagiotis Kanavos has mentioned in the comments, this is usually used for optimistic concurrency checks - to tell if a specific row has changed since the last time it was read. The way you're using it is still valid (keeping the last maximum, and checking the current max to see if any data in the table has changed), although the built-in Change Tracking feature might be attractive to you as an alternative.

Code Snippets

CREATE TABLE dbo.RvTest
(
    Id int NOT NULL,
    rv rowversion,

    CONSTRAINT PK_RvTest PRIMARY KEY (Id)
);
GO

INSERT INTO dbo.RvTest
    (Id)
SELECT DISTINCT 
    [number]
FROM master.dbo.spt_values v1
WHERE 
    v1.[number] IS NOT NULL;
GO

SELECT MAX(rv) FROM dbo.RvTest;
CREATE NONCLUSTERED INDEX IX_rv ON dbo.RvTest (rv DESC);

Context

StackExchange Database Administrators Q#271945, answer score: 3

Revisions (0)

No revisions yet.