Хорошо, так что мне удалось ускорить выполнение пакета с 3 дней до 11 минут.
Я запустил профилировщик и стандартную статистику Windows во время выполнения циклов и обнаружил несколько интересных вещей.
Во-первых, во время выполнения пакетов практически не использовались HDD, CPU, RAM или сеть. Он сказал мне, что я вроде уже знал, что он работал не так быстро, как мог.
Что я заметил, между каждым выполнением цикла была задержка от 1 до 2 мс, прежде чем начал выполняться следующий экземпляр цикла.
В конце концов я обнаружил, что каждый раз, когда начинается новый экземпляр цикла, SSIS создает новое соединение с базой данных SQL, кажется, что это стандартное поведение SSIS. Всякий раз, когда вы создаете источник или назначение, вы добавляете задержку соединения в ваш проект.
Исправление:
Теперь это было странное исправление, вам нужно зайти в свой менеджер соединений (нечетный бит), это должно быть экранное окно, а не правое окно менеджера проекта.
Если вы выберете ваше соединение, на которое ссылается цикл, в окне свойств справа (в любом случае, в моем макете) вы увидите опцию «RetainSameConnection», которая по умолчанию установлена в false.
Установив значение true, я устранил задержку в 2 мс.
Вопросы:
При этом я создал кучу других проблем, которые на самом деле просто выделили области моего пакета, которые я не продумал хорошо.
Некоторые вещи, которые, по-видимому, были затронуты этим изменением, были хранимыми процедурами, которые использовали временные таблицы, они, казалось, мгновенно ломались. Я предполагаю, что из-за того, как SQL обрабатывает временные таблицы, при закрытии соединения и повторном открытии вы можете быть уверены, что временная таблица исчезла. При той же настройке соединения вероятность запуска временных таблиц снова становится проблемой.
Я удалил все временные таблицы и заменил их на операторы CTE, это, кажется, решает эту проблему.
Вторая серьезная проблема, с которой я столкнулся, была связана с параллельными задачами, в которых использовался один и тот же диспетчер соединений. От этого я получил ошибку, что SQL все еще пытается выполнить предыдущую инструкцию. Это взорвало мою посылку.
Чтобы обойти это, я создал дубликат менеджера соединений (всего я создал три менеджера соединений для одной базы данных).
Как только я настроил свои соединения, я вошел в каждый из моих параллельных источников и назначений и назначил им свой собственный менеджер соединений. Похоже, это решило последнюю полученную ошибку.
Вывод:
Они могут быть более непредвиденными проблемами при этом, но сейчас мои пакеты быстро светятся, и это высветило некоторые недостатки в моем дизайне.