Найкращий спосіб реімпортувати велику кількість даних із мінімальним простоєм


11

Мені потрібно імпортувати близько 500 000 записів, що містять дані пошуку IP (лише для читання) приблизно раз на тиждень (лише три cot int / bigint).

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

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

Речі, спробувані поки що

SSIS: Я створив пакет SSIS, який обрізає таблицю та імпортує - для запуску потрібно 30 секунд (насправді занадто довго).

Таблиця темпів: Імпорт у темп-таблицю, обрізання та копіювання в межах також займає близько 30 секунд.

BCP: Навальний імпорт також є занадто повільним (чомусь він повільніше, ніж SSIS (навіть без індексів для підтримки) - я здогадуюсь, що це щось пов'язане з транзакціями char-> int / bigint: /

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

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

Спасибі

Відповіді:


13

Я використовував рішення в минулому (і раніше рекомендував тут і в StackOverflow) - створити дві додаткові схеми:

CREATE SCHEMA shadow AUTHORIZATION dbo;
CREATE SCHEMA cache  AUTHORIZATION dbo;

Тепер створіть імітацію таблиці в cacheсхемі:

CREATE TABLE cache.IPLookup(...columns...);

Тепер, коли ви виконуєте операцію перемикання:

TRUNCATE TABLE cache.IPLookup;
BULK INSERT cache.IPLookup FROM ...;

-- the nice thing about the above is that it doesn't really
-- matter if it takes one minute or ten - you're not messing
-- with a table that anyone is using, so you aren't going to
-- interfere with active users.


-- this is a metadata operation so extremely fast - it will wait
-- for existing locks to be released, but won't block new locks
-- for very long at all:

BEGIN TRANSACTION;
  ALTER SCHEMA shadow TRANSFER    dbo.IPLookup;
  ALTER SCHEMA dbo    TRANSFER  cache.IPLookup;
COMMIT TRANSACTION;


-- now let's move the shadow table back over to
-- the cache schema so it's ready for next load:

ALTER SCHEMA cache TRANSFER shadow.IPLookup;
TRUNCATE TABLE cache.IPLookup; 

-- truncate is optional - I usually keep the data
-- around for debugging, but that's probably not
-- necessary in this case.

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


Дякую, ще одна цікава альтернатива - я думаю, що останні два твердження не зовсім правильні, слід перемістити тінь на кеш і скоротити кеш. Цікаво, чи можна також використовувати синоніми?
Марк

Ти маєш рацію, я все перемішав. Я не впевнений, яким чином синоніми будуть краще, я думаю, що це теж підхід - мати погляд, який вказує на синонім, і змінити базовий синонім транзакції, коли ви заповнили іншу версію. Особисто мені здається, що це трохи краще - коли ви запитуєте dbo.IPLookup, ви знаєте, що це "поточна" таблиця без необхідності переслідувати вигляд та синонім.
Аарон Бертран

FYI я на цьому тижні детальніше розповів про це: sqlperformance.com/2012/08/t-sql-queries/…
Aaron Bertrand
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.