Повышение производительности с транзакциями - PullRequest
0 голосов
/ 26 мая 2020

Я запускаю несколько простых тестов с SQL Server Management Studio v18.5 и SQL Server 12, чтобы проверить возможную миграцию на столбцы Identity или использование последовательностей из-за проблем с производительностью на больших вставках при использовании стратегии вроде INSERT INTO(...); SELECT MAX(ID) + 1 FROM dbo.Test (...); и т. д.

Я получаю более высокую производительность с транзакциями, и я не понимаю и не нахожу причину, почему. транзакции, есть различия в скорости.

Вот код, который я использую:


CREATE TABLE [dbo].[TEST_MIGRATION] (
    [ID] INT NOT NULL,
    [Nome] INT NOT NULL,
    [Pass] INT NOT NULL
);

Тест на INSERT INTO(...); SELECT MAX(ID) + 1 FROM dbo.Test (...);:


BEGIN TRAN

    DECLARE @i int = 1;

    WHILE @i < 10000
    BEGIN
        SET @i = @i + 1;

        INSERT INTO TEST_MIGRATION (ID, Nome, Pass)
        VALUES ((SELECT MAX(ID) + 1 FROM TEST_MIGRATION), @i, @i + 20);
    END

--COMMIT TRAN
ROLLBACK TRAN

Результаты для этого одними были:

[с откатом транзакции]

Результат теста 1:

00: 01: 16

Результат теста 2:

00: 02: 11

[с фиксацией транзакции]

Результат теста 1:

00: 02: 28


Последовательность:


DECLARE @ID INT = (SELECT ISNULL(MAX(ID) + 1, 0) FROM TEST_MIGRATION);

EXEC ('
    CREATE SEQUENCE TEST_MIGRATION_ID_Seq
    START WITH ' + @ID +
    ' INCREMENT BY 1;'
)
;

ALTER TABLE TEST_MIGRATION
ADD CONSTRAINT df_TEST_MIGRATION_ID
DEFAULT (NEXT VALUE FOR dbo.TEST_MIGRATION_ID_Seq) FOR ID
;

BEGIN TRAN

    DECLARE @i int = 1;

    WHILE @i < 10000
    BEGIN
        SET @i = @i + 1;

        INSERT INTO TEST_MIGRATION (Nome, Pass)
        VALUES (@i, @i + 20);

    END

COMMIT TRAN

Результаты для этого были:

[с откатом транзакции]

Результат теста 1:

00: 00: 01

Результат теста 2:

00: 00: 01

Результат теста 3:

00: 00: 02

[С фиксацией транзакции]

Результат теста 1:

00: 00: 01

Результат теста 2:

00: 00: 00

[Без транзакции]

Результат теста 1:

00: 00: 07

Результат теста 2:

00: 00: 08

Результат теста 3:

00: 00: 07


В столбце «Идентификация»:


CREATE TABLE [dbo].[TEST_MIGRATION_IDENTITY] (
    [ID] INT NOT NULL IDENTITY(1, 1),
    [Nome] INT NOT NULL,
    [Pass] INT NOT NULL
);

BEGIN TRAN

    DECLARE @i int = 1;

    WHILE @i < 10000
    BEGIN
        SET @i = @i + 1;

        INSERT INTO TEST_MIGRATION_IDENTITY(Nome, Pass)
        VALUES (@i, @i + 20);

    END

COMMIT TRAN

Это были результаты для этого one:

[With Transaction Rollback]

Результат теста 1:

00: 00: 00

Тест результата 2:

00: 00: 00

[с фиксацией транзакции]

Результат теста 1:

00: 00: 00

Тест результата 2:

00: 00: 00

[Без транзакции]

Результат теста 1:

00: 00: 07

Тест результата 2:

00: 00: 07


TL; DR: Я получаю лучшую производительность с использованием транзакции, в отличие от одних только блоков запросов. Чем это объясняется?

1 Ответ

1 голос
/ 26 мая 2020

Я получаю лучшую производительность с использованием транзакции, в отличие от одних только блоков запроса

Без транзакции SQL Сервер должен проверять sh файл журнала после каждой INSERT. Это физический ввод-вывод, и ваш сеанс после каждого INSERT ожидает, пока журнал будет закреплен на диске.

С транзакцией SQL Сервер не должен проверять sh журнал после каждого INSERT. Вместо этого журнал записывается асинхронно в фоновом режиме, и вам нужно только дождаться, пока последняя запись журнала транзакции не будет закреплена на commit transaction.

...