Ефективно передавати велику кількість (84 мільйонів рядків) даних


11

У мене близько 84 мільйонів рядів. З цих усіх їх потрібно перенести в окрему базу даних на одному сервері, тоді я видаляю, щоб видалити близько 60 мільйонів рядків із вихідної бази даних.

84 мільйони рядків - це все в одній таблиці. Сама таблиця становить 90% всієї бази даних.

Отже ... Джерело: 84 мільйони рядків -> 24 мільйони рядків Місце призначення: 0 рядків -> 84 мільйони рядків

Джерело працює в повному режимі відновлення, призначення буде працювати просто.

Мені цікаво, який би був найефективніший спосіб зробити це?

План A:

1) ВСТАВКА В НАЗАД, ВИБІРТИ * З джерела

2) джерело TRUNCATE

3) ВСТУПИТИ В Джерело SELECT * ІЗ місця призначення, Звідки Keep_condition = 1

План Б:

1) Відновлення резервної копії вихідної бази даних як бази даних призначення

2) Опускайте всі таблиці, крім тієї, яка потрібна в базі даних призначення

3) джерело TRUNCATE

4) ВСТУПИТИ В Джерело SELECT * ВІД місця призначення, де Keep_condition = 1

План C:

1) ВСТАВКА В НАЗАД, ВИБІРТИ * З джерела

2) ВИДАЛИТИ джерело, де зберігати_умова = 0

чи щось інше?

Дякую


чому ви не використовуєте майстра імпорту та експорту даних? це інструмент, що надається при встановленні SQL Server.
Hani El Mouallem

Чи можна скопіювати 24 мільйони рядків у нову таблицю, а потім просто перейменувати два, якщо потрібно, щоб ви ніколи не пересували 84 мільйони рядків без потреби?
LowlyDBA

Це разовий чи триваючий процес? Я прошу, тому що, враховуючи час, який знадобиться на обробку 80М рядків, ймовірно, відбудуться зміни даних у рядах, що виробляють ДЖЕРЕЛО, які тепер мають жити в ДЕСТИНАЦІЇ.
Майкл Грін,

Це виглядає як проблема XY: Вам потрібно закінчити всі 84MM рядків в одній БД, а 24MM - ті, що знаходяться в другій БД. Яка бізнес-вимога вимагає переміщення 84ММ та видалення 60М, а не переміщення 24ММ? посилання: meta.stackexchange.com/questions/66377/what-is-the-xy-problem )
Pieter Geerkens

У мене дуже схожа проблема, і явно це не XY. До розповсюдження законів щодо збереження записів ми зберігали всі дані. Тепер ми повинні видалити рядки, старіші за дату, за якою ми їх вимагаємо законно. Це означає архівування та видалення даних на суму понад 20 років, оскільки зберігання у більшості випадків становить 7 років. Я не думаю, що я один, хто вважає, що Microsoft відмовляється у наданні функцій «масової копії» збереженим процедурам. Додаток не повинен бути швидшим під час руху даних "всередині" БД, ніж сам БД. Наступного року ще один рік має бути заархівовано.
bielawski

Відповіді:


11

Я хотів би додати, що як би ви не вирішили підійти до цього, вам потрібно буде проводити пакет цих транзакцій . Останнім часом мені дуже пощастило із пов’язаною статтею, і я ціную те, як вона використовує індекси на відміну від більшості пакетних рішень, які я бачу.

Навіть мінімально зареєстровані, це великі транзакції , і ви можете витратити багато часу, займаючись наслідками ненормального росту журналу (VLF, обрізання, розмір права тощо).

Дякую


3

"Ефективне" може застосовуватися для використання файлів журналу, продуктивності вводу / виводу, часу процесора чи часу виконання.

Я б спробував досягти мінімально зареєстрованої операції, яка була б досить ефективною з точки зору ведення журналу. Це повинно заощадити певний час виконання, як бонус. Якщо у вас є простір tempdb, для вас може працювати наступне.

CREATE TABLE #temp;
ALTER source -> BULK_LOGGED recovery model

BEGIN TRANSACTION;

    INSERT INTO dest SELECT FROM source;
    INSERT INTO #temp SELECT FROM source WHERE keep_condition=1;
    TRUNCATE TABLE source;
    INSERT INTO source SELECT FROM #temp;

COMMIT TRANSACTION;

ALTER source -> FULL recovery model
DROP TABLE #temp;

Щоб відбулася операція з мінімально зареєстрованим журналом, має виконуватися ряд умов, включаючи відсутність резервних копій, які зараз виконуються, базу даних, встановлену в BULK_LOGGEDрежимі відновлення, і залежно від ваших індексів цільова таблиця може бути порожньою. Частина цієї поведінки також змінилася (покращилася) від SQL Server 2005 до 2008 року.

Потім знову, не знаючи специфіки вашої таблиці та даних, будь-який із інших ваших варіантів може бути кращим. Спробуйте використовувати

SET STATISTICS IO ON;
SET STATISTICS TIME ON;

.. і подивіться, що працює найкраще.

РЕДАКТУВАННЯ . Під час виконання операцій з масовим журналом переконайтесь, що ви робите резервну копію (повний журнал трансакцій) до та після операції, якщо вам потрібна можливість відновлення в часі і ви підозрюєте, що в базі даних може відбуватися інша діяльність в той же час, коли працює ваше ETL.

Я писав щоденник в блозі про мінімально зареєстровані операції деякий час тому, там є посилання на інші пости та документацію.


+1 для поради OP для тестування, щоб побачити, що краще. Звичайно, це може бути дещо складно отримати реальні цифри, якщо у них немає дублікату системи у програмі тощо.
Макс Вернон,

Лише запитання: Що буде, якщо ви спробуєте відновити момент часу, коли база даних була в режимі масового входу? Я вважав, що будь-яка транзакція, яка не кваліфікується як "основна", може бути відшкодована.
elty123

1
@ elty123 Відновлення в масовому режимі можна відновити лише до кінця останньої резервної копії журналу. Немає сенсу часу відновлення, як це було б при повному одужанні. Зазвичай ви переходите до відновлення масової реєстрації, запускаєте деякий процес ETL, повертаєтесь до повного і потім робите резервну копію журналу.
RubberChickenLeader

@WindRaven Це невірно - див. Мою відповідь нижче.
wBob

1
@wBob та @WindRaven, я оновив свою відповідь, щоб відобразити необхідність робити резервні копії до та після використання BULK_LOGGEDрежиму. Дякую!
Даніель Хатмахер

1

Чому б не БКП?

  1. Завантажте резервну частину
  2. Змініть джерело на груповий запис
  3. Відкрити командний рядок

  4. bcp server.sourcedb.table out Filename.flt -T -c

  5. bcp "SELECT * FROM sourcedb.table WHERE keep_condition = 1" queryout Filename2.flt -T -c

  6. bcp Server.destinationdb.table in Filename.flt -T -c -b1000

  7. перевірити дані

  8. З SSMS Обрізати таблицю джерел
  9. bcp server.sourcedb.table in Filename2.flt -T -c -b1000
  10. Зміна джерела повернення на повний

2
Тому що вони на одному сервері. Запис у файлову систему буде дорогим. Краще створити базу даних і натиснути її, сподіваємось скористатися миттєвою ініціалізацією файлів. Це був би розумний вибір для dbs на різних серверах, хоча SSIS був би моїм першим вибором, якщо він буде доступний. Примітка: Варіант -n (рідний) є більш компактним та безпечнішим для переміщення даних із SQL Server на SQL Server. Варіант -b не впливає на вихід bcp.
wBob

0

Не думайте, що вам слід рекомендувати змінити модель відновлення без повної резервної копії бази даних або резервної копії t-log до і після . Однією з особливостей моделі відновлення BULK_LOGGED є те, що ви втратите можливість виконувати точне час відновлення для t-журналів, що містять операції масового входу. Класичний сценарій: нічне повне резервне копіювання, погодинна резервна копія t-log. Ви змінюєте модель відновлення на масовий запис і починаєте свою операцію. Щось піде не так, і транзакція відкочується назад (або ви її не використали). Однак ви не впевнені, що ще відбувається в базі даних, тому ви хочете відновити до відомого хорошого моменту.

Коли можна відновити назад? Остання погодинна резервна копія t-log, яка не містить операцій масового входу, потенційно втрачає n хвилин транзакцій. Повне резервне копіювання або t-log резервного копіювання перед зміною моделі відновлення створить точку резервного копіювання. Який ви обираєте, залежить від вашої RTO.


0

Видалення розділів із таблиці - це дійсно швидкий і ресурсоефективний спосіб видалення великих фрагментів даних із таблиці. Якби ця таблиця була розділена таким чином, що підтримує розділення джерела / місця призначення, відповідь буде відновити копію, видалити зайві таблиці та надлишкові розділи з пункту призначення та видалити додаткові розділи з джерела.

Однак вартість включення розділу може зробити цю операцію дорожчою в цілому.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.