Производительность обновления таблицы уменьшается с количеством строк - PullRequest
0 голосов
/ 07 июня 2018

Я пишу запрос на обновление большой таблицы (более 6 миллиардов строк).К сожалению, вставка в новую таблицу невозможна из-за ограничений дискового пространства.

Я провел тестирование производительности с обоими ответами на заданный вопрос здесь , и второй ответ, кажется, самый быстрый вариант.

Я проверил производительность запросов с 1, 2, 3, 5 и 10 миллионами строк.Производительность резко снижается, чем больше строк я добавляю в обновление.

Вот пример моего запроса на обновление:

DECLARE @Rows INT, @BatchSize INT;
SET @BatchSize = 4500;

SET @Rows = @BatchSize; 

WHILE (@Rows = @BatchSize)
BEGIN
    UPDATE TOP (@BatchSize) [dbo].[TestTable]
    SET MyID1 = MyID2
    FROM  [dbo].[TestTable]
    WHERE MyID1 <> MyID2

    SET @Rows = @@ROWCOUNT;
END

Время завершения и количество обновляемых строк в секунду:

  • 1 миллион строк: завершено 43 секунды, 23255 строк / секунду
  • 2 миллиона строк: завершено 168 секунд, 11904 строки / секунда
  • 3 миллиона строк: 366секунд до завершения, 8196 строк / секунду
  • 5 миллионов строк: 1098 секунд до завершения, 4553 строки / секунду
  • 10 миллионов строк: 3922 секунды до завершения, 2549 строк / секунду

Я бы предположил, что смогу усреднять количество строк в секунду и получить оценку времени до завершения, но время до завершения, кажется, растет в геометрической прогрессии.Например, удвоение времени для завершения 5 миллионов строк должно занять около 2200 секунд, но это займет 3922 секунды.

Тестирование несколько раз возвращает похожие результаты, поэтому я не думаю, что имею дело с проблемой раздора.Плюс, это на тестовом сервере, который не используется.Чего мне здесь не хватает и как мне точно рассчитать время завершения этого обновления?

1 Ответ

0 голосов
/ 08 июня 2018

Мне удалось найти эффективный запрос на обновление.Приведенный ниже запрос обновляет 5 миллионов строк за 15 секунд и 10 миллионов строк за 30 секунд.

Я создал кластерный индекс для столбца BatchKey, который является столбцом целочисленных идентификаторов.Затем написал запрос для цикла по строкам на основе Min и Max BatchKey.

DECLARE @MaxKey BIGINT, @MinKey BIGINT, @iMax BIGINT, @iMin BIGINT

SELECT 
    @MinKey = MIN(BatchKey), 
    @MaxKey = MAX(BatchKey)
FROM dbo.TestTable

SET @iMin = @MinKey         -- starting minimum key
SET @iMax = @MinKey + 4500  -- starting maximum key for batch

WHILE (@iMin < @MaxKey) 
BEGIN
    UPDATE dbo.TestTable
    SET MyID1 = MyID2
    FROM  dbo.TestTable
    WHERE BatchKey >= @iMin
    AND BatchKey <= @iMax

    SET @iMin = @iMax + 1       -- get next minimum key
    SET @iMax = @iMin + 4500    -- get next maximum batch key

END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...