SSIS зависает во время обновления с 3 миллионами строк - PullRequest
0 голосов
/ 03 декабря 2018

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

Все таблицы работают очень хорошо, за исключением 1 таблицы, в которой в источнике более 3 миллионов строк,как вы увидите на изображении ниже, он просто запускается, но никогда не заканчивается.Возможно, я не делаю обновление правильно или есть другой способ сделать это.

Вот несколько фотографий моего пакета служб SSIS: ControlFlow

Подсвеченный объект находится там, где он висит.DataFlow Это хранимая процедура, которую я вызываю для обновления таблицы:

ALTER PROCEDURE [dbo].[UpdateDim_A] 
      @ID INT,
      @FileDataID INT
     ,@CategoryID SMALLINT
     ,@FirstName VARCHAR(50)
     ,@LastName VARCHAR(50)
     ,@Company VARCHAR(100)
     ,@Email VARCHAR(250) AS BEGIN
SET NOCOUNT ON;


BEGIN TRAN 
 UPDATE DIM_A 
    SET                  
        [FileDataID] = @FileDataID,
        [CategoryID] = @CategoryID,
        [FirstName]  = @FirstName,
        [LastName]   = @LastName,
        [Company]    = @Company,
        [Email]      = @Email

    WHERE PartyID=@ID

    COMMIT TRAN;  END

Примечание: Я уже пытался удалить ограничение и индексы и изменить восстановлениережим базы данных простой.

Любая помощь будет признательна.


После Примените решение, предоставленное @Prabhat G, так выглядит мой пакет:за 39 секунд (в среднем) !!!

fIXED5

Inside Dim_A DataFlow enter image description here

Ответы [ 3 ]

0 голосов
/ 03 декабря 2018

Таким образом, ваша проблема на самом деле очень проста - метод, который вы используете, выполняет эту хранимую процедуру для каждой возвращаемой строки.Если у вас есть 9961 (как на вашей картинке) строк для обновления, то этот оператор запустит 9961 отдельное время.Скорее всего, если вы посмотрите на активные запросы, выполняемые на сервере SQL, вы увидите, что эта процедура выполняется снова и снова.

Чтобы ускорить это, вы должны сделать дамп этих данных в промежуточную таблицу, а затем использовать задачу выполнения SQL в вашем пакете для запуска стандартного обновления SQL.Это будет работать намного быстрее.

0 голосов
/ 04 декабря 2018

Следуйте этим 2 улучшениям производительности, и вы избежите своего узкого места.

  1. Удалите sort преобразование.В вашем источнике при получении данных используйте order by sql. Причина в том, что sort занимает все записи в памяти перед сортировкой.Вы не хотите этого, будь то инкрементная или полная загрузка.

  2. На последнем этапе обновления введите другую промежуточную таблицу вместо update records oledb command, которая будет копией таблицы Dim,После того, как все соответствующие записи будут вставлены в эту новую промежуточную таблицу, выйдите из задачи потока данных и создайте EXECUTE SQL TASK, которая будет просто ОБНОВЛЯТЬ таблицу затемнения на основе идентификатора / условий соединения.

Причина для этого заключается в том, что команда oledb поражает строку за строкой.Всегда предпочитайте обновление, используя Execute SQL Task в качестве пакетного процесса.


Редактировать: Согласно комментариям, чтобы обновить только измененные строки в Execute SQL Task, добавьте условия в предложении where:

eg:

UPDATE x
SET
   x.attribute_A = y.attribute_A
  ,x.attribute_B = y.attribute_B
FROM
DimA x
 inner join stg_DimA y
ON x.Id = y.Id
WHERE
(x.Attribute_A <> y.Attribute_A
OR x.Attribute_B <> y.Attribute_B)
0 голосов
/ 03 декабря 2018

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

UPDATE DIM_A 
SET FileDataID = ?
    ,CategoryID = ?
    ,FirstName = ?
    ,LastName = ?
    ,Company = ?
    ,Email = ?
WHERE PartyID = ?

Примечание. @Id должен быть включен в столбец в вашем столбце.поток данных.

И последнее, что вы должны учитывать, как правильно указал Зейн: вы должны обновлять только те строки, которые изменились.Итак, в вашем потоке данных вы должны добавить преобразование «Условное разбиение», которое проверяет, отличаются ли какие-либо столбцы в новой исходной строке от существующих строк таблицы.Команде OLE DB следует отправлять только строки, отличающиеся друг от друга, остальные можно игнорировать.

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