Как исправить медленно работающий пакет служб SSIS - PullRequest
1 голос
/ 24 апреля 2019

Я пытаюсь вставить большой объем данных из одной таблицы из БД ПРОД в таблицу в БД архива.Таблицы с идентичной схемой, а архивная таблица с пониженными индексами и «Идентификационная вставка включена».Мне нужно вставить только записи, которых нет в Arh DB / Table.Я использую «Выполнить задачу SQL» в пакете последовательностей служб SSIS, и он работает очень медленно (используется размер пакета вставки 20000). У меня вставлено 20000 записей в течение 10 минут. Стоит отметить, что мне нужно вставить 48000000 записей.SQL-сервер является стандартом 2016 года edt.Есть ли какое-то решение для этого.

SQL-запрос:

SELECT TOP (@InsertBatchSize) s.ID,.....and other columns 
FROM PRODDB.dbo.source_table AS s WITH (NOLOCK) 
    INNER JOIN ArchiveDB.dbo.MissingIDsTable AS t WITH (NOLOCK) 
    ON s.ID = t.ID 
WHERE s.ID not in (SELECT ID 
                   from ArchiveDB..destination_table 
                   WHERE IsUpdated is null ) 

Ответы [ 2 ]

0 голосов
/ 24 апреля 2019

Execute SQL не подходит для передачи данных. Он не может ни пакетировать данные, ни преобразовывать их. Это работа задач Dataflow. Задачи потока данных позволяют считывать исходные данные, используя курсор пожарного шланга, и записывать их в цель данных с помощью пакетных операций с использованием минимального ведения журнала. Его скорость зависит от исходного запроса. Медленный запрос приведет к медленному выполнению.

В вопросе отсутствует много информации, например, схемы таблиц как в исходной, так и в целевой базе данных. Начиная с "Identity insert on" я подозреваю, что в таблицах есть столбец ID, который является IDENTITY и первичным ключом в источнике. Если вас интересуют только новые записи, вы можете написать исходный запрос, который считывает данные только с момента последнего выполнения, например:

SELECT s.ID,.....and other columns 
FROM PRODDB.dbo.source_table AS s
where ID>@maxId

Где @maxId - параметр запроса, предоставленный исходному запросу. Нет необходимости в пакетировании, SSIS может сделать это на основе источника данных, целевых настроек размера пакета и т. Д.

Этот запрос следует использовать только для загрузки новых данных. Для создания начальной копии используйте другой поток данных, исходный запрос которого ничего не фильтрует. Использование что-то вроде Where ID>-1 вернет все данные, но только после сканирования всего индекса. Почему это , когда мы уже собираемся скопировать все данные?

Идентификатор также должен быть первичным ключом в таблице target . Это ускорит операцию select MAX(ID) from target, которая загружает значение параметра. Это также обнаружит и предотвратит неизбежные ошибки дублирования. Независимо от того, насколько мы осторожны, другие всегда делают ошибки, которые могут привести к дублированию данных.

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

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

Вы также можете скопировать измененные данные в промежуточную таблицу и объединить , что с целью изменения INSERT / UPDATE. Идентификатор или отслеживание изменений можно использовать для поиска измененных данных. Это дает преимущество быстрого освобождения источника.

0 голосов
/ 24 апреля 2019

Задача - передача данных между базами данных, целевая БД находится на сервере SQL 2016.
Я бы порекомендовал следующий подход:

  1. Создание в ArchDB таблиц для поэтапной загрузки. Лучше создать его в отдельной схеме и с теми же именами, что и в исходных таблицах, только для удобства и удобства чтения.
  2. Создайте пакет служб SSIS, выполнив следующие действия:

    • Очистить необходимую промежуточную таблицу в задаче Exec SQL
    • Задача потока данных - переместить все данные из источника в промежуточную таблицу в ArchDB. В потоке данных - определите компонент Lookup с полным кэшем на основе целевой таблицы ArchDB; этот компонент будет проверять записи на наличие в ArchDB. Подбирайте только пропущенные записи.
    • Переместить данные из промежуточной таблицы в Arch DB в целевую таблицу, как

    Вставить в (TABLOCK) SELECT ... FROM

Комментарии:

  • Компонент поиска в DFT служит для фильтрации существующих записей. Поскольку у вас нет никаких индексов в целевой таблице ArchDB, вы должны использовать полный кеш со стоимостью большого объема оперативной памяти.
  • INSERT WITH (TABLOCK) сжатие используется для использования функции параллельной вставки SQL 2016.
  • Вы можете обойтись без промежуточных таблиц и вставить прямо в целевой стол. Однако отладка будет более сложной.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...