Що найкращий спосіб архівувати весь, крім поточного року, та розділити таблицю одночасно


23

Завдання

Заархівуйте всі великі таблиці, окрім постійного періоду, з групи великих таблиць. Заархівовані дані повинні зберігатися в іншій базі даних.

  • База даних знаходиться в простому режимі відновлення
  • Таблиці складають від 50 млн. Рядків до декількох мільярдів і в деяких випадках займають сотні ГБ кожен.
  • Наразі таблиці не розміщені в розділі
  • Кожна таблиця має один кластерний індекс у стовпці, що постійно збільшується
  • Кожна таблиця додатково має один некластеризований індекс
  • Усі зміни даних у таблицях є вставками
  • Мета - мінімізувати час простою первинної бази даних.
  • Сервер - 2008 R2 Enterprise

Таблиця «архіву» матиме близько 1,1 мільярда рядків, «жива» таблиця - близько 400 мільйонів. Очевидно, архівна таблиця з часом збільшиться, але я очікую, що і жива таблиця теж швидко зросте. Скажіть 50% принаймні протягом наступних двох років.

Я думав про бази даних розтягування Azure, але, на жаль, ми знаходимось у R2 2008 року і, ймовірно, залишимось там на деякий час.

Поточний план

  • Створіть нову базу даних
  • Створіть нові таблиці з розподілом по місяцях (використовуючи змінену дату) у новій базі даних.
  • Перемістіть останні 12-13 місяців даних у розділені таблиці.
  • Зробіть своп перейменування двох баз даних
  • Видаліть переміщені дані з бази даних "архіву".
  • Розділіть кожну з таблиць у базі даних «архіву».
  • Використовуйте свопи розділів для архівації даних у майбутньому.
    • Я розумію, що мені доведеться підміняти дані, які потрібно архівувати, скопіювати цю таблицю в базу даних архіву, а потім поміняти їх у таблицю архіву. Це прийнятно.

Проблема: я намагаюся перемістити дані в початкові розділені таблиці (адже я все ще роблю підтвердження своєї концепції). Я намагаюся використовувати TF 610 (відповідно до Посібника з продуктивності завантаження даних ) та INSERT...SELECTоператора для переміщення даних, спочатку вважаючи, що вони будуть мінімально зареєстровані. На жаль, кожен раз, коли я намагаюся, він повністю реєструється.

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

Чи є щось, чого мені не вистачає в моєму загальному плані, і чи найкращим є SSIS для швидкого переміщення даних та з мінімальним використанням журналу (проблеми з простором)?

Демо-код без даних

-- Existing structure
USE [Audit]
GO

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
); 
-- ~1.4 bill rows, ~20% in the last year

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(   [Modified] ASC   )
GO


-- New DB & Code
USE Audit_New
GO

CREATE PARTITION FUNCTION ThirteenMonthPartFunction (datetime)
AS RANGE RIGHT FOR VALUES ('20150701', '20150801', '20150901', '20151001', '20151101', '20151201', 
                            '20160101', '20160201', '20160301', '20160401', '20160501', '20160601', 
                            '20160701') 

CREATE PARTITION SCHEME ThirteenMonthPartScheme AS PARTITION ThirteenMonthPartFunction
ALL TO ( [PRIMARY] );

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
) ON ThirteenMonthPartScheme (Modified)
GO

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

CREATE NONCLUSTERED INDEX [AuditTable_Col1_Col2_Col3_Col4_Modified] ON [dbo].[AuditTable]
(
    [Col1] ASC,
    [Col2] ASC,
    [Col3] ASC,
    [Col4] ASC,
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

Перемістити код

USE Audit_New
GO
DBCC TRACEON(610);

INSERT INTO AuditTable
SELECT * FROM Audit.dbo.AuditTable
WHERE Modified >= '6/1/2015'
ORDER BY Modified

RE "переміщення даних": Щоб мінімізувати використання журналу, ви можете переміщувати дані в партіях, наприклад, "Approch 2" в dba.stackexchange.com/a/139009/94130 . Що стосується розбиття, чи розглядали ви розділені погляди?
Олексій

@ Алекс Так, я розглядав і те, і інше. Мій план резервного копіювання - переміщення даних у партіях за допомогою SSIS. І в цьому конкретному випадку моє питання полягає саме в тому, для чого створений перегородка. (швидке завантаження / вивантаження даних за допомогою комутації)
Кеннет Фішер

Відповіді:


10

Чому ви не отримуєте мінімальну реєстрацію?

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

введіть тут опис зображення

Рекомендований підхід

Виходячи з рекомендацій у Посібнику з продуктивності завантаження даних (включаючи розділ «Масове завантаження розділеної таблиці»), а також великому досвіді завантаження розділених таблиць на десятки мільярдів рядків, ось такий підхід я рекомендував би:

  • Створіть нову базу даних.
  • Створіть нові таблиці, розподілені по місяцях у новій базі даних.
  • Перемістіть дані останнього року наступним чином:
    • Для кожного місяця створюйте нову таблицю купи;
    • Вставте дані місяця в купу за допомогою підказки TABLOCK;
    • Додайте кластерний індекс у купу, що містить цей місяць даних;
    • Додайте обмеження чека, що підтверджує, що таблиця містить дані лише цього місяця;
    • Переключіть таблицю у відповідний розділ нової загальної таблиці.
  • Зробіть своп перейменування двох баз даних.
  • Обрізати дані в тепер "архівній" базі даних.
  • Розділіть кожну з таблиць у базі даних «архіву».
  • Використовуйте свопи розділів для архівації даних у майбутньому.

Відмінності порівняно з вашим оригінальним підходом:

  • Методика переміщення даних за останні 12-13 місяців буде набагато ефективнішою, якщо ви завантажуєте в групу TABLOCKодин місяць за один раз, використовуючи перемикання розділів, щоб розмістити дані в розділену таблицю.
  • DELETEРозчистити старий стіл буде повністю увійшли. Можливо, ви можете TRUNCATEабо скинути таблицю і створити нову таблицю архіву.

Порівняння підходів для переміщення даних за останній рік

Щоб порівняти підходи за розумну кількість часу на моїй машині, я використав 100MM rowтестовий набір даних, який я створив і який відповідає вашій схемі.

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

введіть тут опис зображення

Ось повний скрипт тесту .

Підсумкові ноти

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

Наприклад, я застосував рекомендований підхід на фактичному сервері розробників (Dell R720) і побачив зменшення до 76 seconds156 secondsмого ноутбука). Цікаво, що оригінальний підхід до вставки в розділену таблицю не зазнав такого ж покращення і все-таки перейняв лише 12 minutesсервер розробників. Імовірно, це тому, що ця модель дає план послідовного виконання, і один процесор на моєму ноутбуці може відповідати одному процесору на сервері розробників.


Ще раз дякую Джеффу. Я використовую метод SWITCH. Зокрема, я використовую SSIS та динамічний SQL для запуску 13 місяців паралельно.
Кеннет Фішер

1

Це може бути хорошим кандидатом для Бімля. Одним із підходів було б створення шаблону для багаторазового використання, який мігрував би дані для однієї таблиці в невеликих діапазонах дат із контейнером "Для кожного". Biml буде проходити через вашу колекцію таблиць, щоб створити однакові пакети для кожної класифікації. Енді Леонард має вступ до своєї серії Сходи .


0

Можливо, замість створення нової бази даних відновіть реальну базу даних до нової бази даних та видаліть найновіші 12-13 місячні дані. Потім видаліть із реальної бази даних ті дані, які не містяться у вашій щойно створеній області архіву. Якщо великі видалення є проблемою, можливо, ви можете просто видалити 10K або більші набори за допомогою сценарію, щоб це зробити.

Ваші завдання розділення не здаються, що вони будуть заважати, і, здається, застосовні до будь-якої бази даних після видалення.


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