9

我计划添加到我的数据库 rowversion 中的大多数表中,以跟踪这些表中的更改。我知道添加它会影响查询的性能。

有谁知道它是否会稍微影响性能(慢几个百分点)或者我不应该将 rowversion 添加到许多表中,因为它会使 DB 慢得多。

4

2 回答 2

5

仅添加 rowversion/timestamp 列的性能差异在于您的行现在宽了 8 个字节。

当您开始实际使用它们时,实际的性能差异就会出现。但正如我在回答类似问题时指出的那样:RowVersion and Performance

如果您不打算使用该rowVersion字段来检查更新的项目,而是要使用它来保持一致性,以确保自上次阅读后记录没有更新,那么这将是一个完全可以接受的用途,并且不会影响。

如:

UPDATE MyTable SET MyField = ' @myField
WHERE Key = @key AND rowVersion = @rowVersion

因此,仅检查行以确保自应用程序上次读取以来它没有被更新时的性能将是微不足道的性能差异(无论如何它必须读取行来更新它)。

但是,当尝试使用 rowversion/timestamp 列作为获取自上次检查以来所有更新项目的方法时,性能将非常差。

于 2011-11-01T06:30:49.313 回答
2

我感兴趣的是,我们使用的版本控制是由触发器填充的,所以当我看到这个时,我必须了解更多关于性能的信息。所以,我开始设置一个测试场景。我想将我们当前使用的(触发器)与 rowversion 列与另一个没有版本控制的表进行比较。

毫不奇怪,触发器的性能肯定比 rowversion 差。Rowversion 基本上与没有版本控制的表上的更新时间相同;一些运行显示没有版本控制的表更快,但大约等于 # show rowversion 更快。对我来说,这意味着使用它的开销很小,随机 CPU 和磁盘 I/O 隐藏了真正的性能差异。

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
于 2015-10-08T21:08:09.697 回答