Of interest to me, the versioning we use is populated by trigger, so when I saw this I had to learn more about the performance. So, I set about setting up a test scenario. I wanted to compare what we currently use (trigger) versus a rowversion column versus another table with no versioning.
Not surprisingly, the trigger definitely performed worse than the rowversion. Rowversion was essentially identical to the update time on a table with no versioning; Some runs show the table with no versioning is faster, but about an equal # show rowversion to be faster. To me this means that there is so little overhead in using it, that random CPU and disk I/O hide the real performance difference.
SET NOCOUNT ON
GO
CREATE TABLE _TEST_BaseTest(myKey bigint PRIMARY KEY,myValue bigint,UselessColumn bigint)
CREATE TABLE _TEST_RowVersionTest(myKey bigint PRIMARY KEY,myValue bigint, RV rowversion)
CREATE TABLE _TEST_ModifiedVersionTest(myKey bigint PRIMARY KEY,myValue bigint, MV bigint)
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER dbo._TEST_ModifiedVersionTest_Trigger
ON dbo._TEST_ModifiedVersionTest
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
UPDATE tbl
SET tbl.MV=tbl.MV+1
FROM _TEST_ModifiedVersionTest tbl
INNER JOIN inserted i on i.myKey=tbl.myKey
END
GO
INSERT INTO _TEST_BaseTest (myKey,myValue)
SELECT TOP 50000 <FIELD1>,<FIELD2> FROM <SOME_TABLE>
INSERT INTO _TEST_RowVersionTest (myKey,myValue)
SELECT myKey,myValue
FROM _TEST_BaseTest
INSERT INTO _TEST_ModifiedVersionTest (myKey,myValue,MV)
SELECT myKey,myValue,1
FROM _TEST_BaseTest
DECLARE @StartTimeBase DATETIME, @EndTimeBase DATETIME
, @StartTimeRV DATETIME, @EndTimeRV DATETIME
, @StartTimeMV DATETIME, @EndTimeMV DATETIME
, @CNT INT=0, @Iterations INT=25
--BASE
SET @StartTimeBase=GETDATE()
SET @CNT=1
WHILE @CNT<=@Iterations
BEGIN
UPDATE _TEST_RowVersionTest SET myValue=myValue
SET @CNT=@CNT+1
END
SET @EndTimeBase=GETDATE()
--RV
SET @StartTimeRV=GETDATE()
SET @CNT=1
WHILE @CNT<=@Iterations
BEGIN
UPDATE _TEST_RowVersionTest SET myValue=myValue
SET @CNT=@CNT+1
END
SET @EndTimeRV=GETDATE()
--MV
SET @StartTimeMV=GETDATE()
SET @CNT=1
WHILE @CNT<=@Iterations
BEGIN
UPDATE _TEST_ModifiedVersionTest SET myValue=myValue
SET @CNT=@CNT+1
END
SET @EndTimeMV=GETDATE()
DECLARE @Rows INT
SELECT @Rows=COUNT(*) FROM _TEST_BaseTest
PRINT CONVERT(VARCHAR,@Rows) + ' rows updated ' + CONVERT(VARCHAR,@Iterations) + ' time(s)'
PRINT CONVERT(VARCHAR,DATEDIFF(MS,@StartTimeBase,@EndTimeBase)) + ' Base Time Elapsed (ms)'
PRINT CONVERT(VARCHAR,DATEDIFF(MS,@StartTimeRV,@EndTimeRV)) + ' Rv Time Elapsed (ms)'
PRINT CONVERT(VARCHAR,DATEDIFF(MS,@StartTimeMV,@EndTimeMV)) + ' Mv Time Elapsed (ms)'
drop TABLE _TEST_BaseTest
drop TABLE _TEST_RowVersionTest
drop table _TEST_ModifiedVersionTest