Влияет ли rowversion / timestamp на производительность? - PullRequest
8 голосов
/ 28 августа 2011

Я планирую добавить большинство таблиц в моей версии БД для отслеживания изменений в этих таблицах. Я знаю, что его добавление повлияет на производительность запросов.

Кто-нибудь знает, немного ли это влияет на производительность (на несколько процентов медленнее), или мне не следует добавлять преобразование строк во многие таблицы, потому что это делает БД намного медленнее.

Ответы [ 2 ]

5 голосов
/ 01 ноября 2011

Разница в производительности при добавлении столбца rowversion / timestamp заключается в том, что ваши строки теперь на 8 байт шире.

Реальная разница в производительности возникает, когда вы начинаете использовать их для чего-то. Но, как я отмечаю в своем ответе на аналогичный вопрос: RowVersion and Performance

Если вы не собираетесь использовать поле rowVersion для проверки обновленных элементов, и вместо этого вы собираетесь использовать его для согласованности, чтобы гарантировать, что запись не обновляется с момента вашего последнего чтения, тогда это будет будет вполне приемлемым и не повлияет.

Например:

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

Таким образом, производительность при простой проверке строки, чтобы убедиться, что она не была обновлена ​​с момента последнего чтения приложения, будет тривиальной разницей в производительности (она все равно должна прочитать строку, чтобы обновить ее).

Но производительность при попытке использовать столбец rowversion / timestamp в качестве средства для получения всех обновленных элементов со времени последней проверки будет очень низкой.

1 голос
/ 09 октября 2015

Меня интересует, что версия, которую мы используем, заполняется триггером, поэтому, когда я увидел это, мне пришлось больше узнать о производительности.Итак, я приступил к настройке тестового сценария.Я хотел сравнить то, что мы в настоящее время используем (триггер), со столбцом версии строки и другой таблицей без контроля версий.

Не удивительно, что триггер определенно работал хуже, чем версия строки.Rowversion был практически идентичен времени обновления таблицы без контроля версий;Некоторые прогоны показывают, что таблица без управления версиями быстрее, но примерно равна # show rowversion, чтобы быть быстрее.Для меня это означает, что при его использовании накладных расходов так мало, что случайный процессор и дисковый ввод-вывод скрывают реальную разницу в производительности.

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
...