Импорт новой таблицы базы данных

Там, где я нахожусь, есть основная система, работающая на большом мэйнфрейме AIX. Для создания отчетов и операций каждую ночь выполняется дамп с мэйнфрейма в SQL Server, так что каждый из наших 50-ти клиентов находится в своей собственной базе данных с идентичными схемами. На создание этого дампа уходит около 7 часов каждую ночь, и на самом деле мы ничего не можем с этим поделать: мы застряли на том, что предоставил поставщик приложения.

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

Процесс импорта этой таблицы сам по себе занимает пару часов. Он фильтрует около 40 миллионов записей, распределенных по 50 базам данных, примерно до 4 миллионов записей, а затем индексирует их по определенным столбцам для поиска. Даже в несколько часов это меньше, чем треть начальной загрузки, но у нас не хватает времени для ночной обработки, мы не контролируем дамп мэйнфрейма, и мы это контролируем. Поэтому мне было поручено найти способы улучшить существующую процедуру.

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

Итак, мой вопрос: какой способ загрузки этой таблицы был бы наиболее эффективным? Правы ли мы, считая, что индексация позже лучше? Или мы должны создать индексы перед импортом данных? Должны ли мы загружать таблицу в порядке индекса, чтобы избежать массового переупорядочения страниц, а не сначала крупным клиентам? Может ли параллельная загрузка усугубить ситуацию, вызвав одновременный доступ к большому количеству дисков или лишив нас возможности контролировать порядок? Есть другие идеи?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
268
4

Ответы 4

Насколько мне известно, вы правы - гораздо лучше добавить все записи сразу, а затем индексировать один раз в конце.

Я довольно много работал с загрузкой массовых наборов данных в SQL Server и провел некоторое тестирование производительности индекса при вставке и последующем добавлении. Я обнаружил, что НА ДАЛЬШЕ было гораздо эффективнее создавать индекс после загрузки всех данных. В нашем случае загрузка заняла 1 час с добавленным индексом в конце и 4 часа, чтобы добавить его с включенным индексом.

Я думаю, что главное - как можно быстрее переместить данные, я не уверен, действительно ли помогает их загрузка по порядку, есть ли у вас статистика по времени загрузки и времени индекса? Если вы это сделаете, вы можете начать немного поэкспериментировать с этой стороной дела.

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

Вы можете получить выигрыш в производительности, используя bcp для загрузки данных в промежуточную область и параллельно выполняя несколько задач (SSIS сделает это). Напишите универсальную оболочку пакетного файла для bcp, которая принимает путь к файлу (и имя таблицы, если необходимо) и вызывает серию заданий в полдюжине потоков с задачами «Выполнить процесс» в SSIS. Для 50 заданий, вероятно, не стоит пытаться написать процесс контроллера нагрузки, управляемый данными. Оберните эти задачи в контейнер последовательности, чтобы вам не приходилось явно поддерживать все зависимости.

Вам обязательно следует отбросить и заново создать индексы, так как это значительно сократит количество операций ввода-вывода во время процесса.

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

Индексируйте в конце, да. Также рассмотрите возможность установки параметра уровня журнала на BULK LOGGED, чтобы минимизировать запись в журнал транзакций. Просто не забудьте вернуть его в ПОЛНЫЙ после того, как закончите.

Другие вопросы по теме

Похожие вопросы