Лучший способ повторно импортировать большой объем данных с минимальным временем простоя


11

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

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

В идеале запросы, выполняющиеся над данными, продолжали бы выполняться (мы не получаем много из них, и для них приемлемо выполняться немного медленнее, пока происходит импорт, но их необходимо выполнять 24/7, так что выполняйте это » вне часов "не вариант).

Вещи пробовали до сих пор

SSIS: я создал пакет SSIS, который усекает таблицу и импортирует ее - для ее запуска требуется около 30 секунд (на самом деле, это слишком долго).

Temp Table: Импорт в временную таблицу, усечение и копирование также занимает около 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.

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


Спасибо, еще одна интересная альтернатива - я думаю, что последние два утверждения не совсем правильные, они должны перемещать тень в кеш и урезать кеш. Интересно, можно ли использовать синонимы?
Mark

Вы правы, я все перепутал. Я не уверен, как именно синонимы будут лучше, я думаю, что это тоже подход - иметь представление, которое указывает на синоним, и изменять базовый синоним в транзакции, когда вы заполнили другую версию. Лично я нахожу это немного лучше - когда вы запрашиваете dbo.IPLookup, вы знаете, что это «текущая» таблица без необходимости искать представление и синоним.
Аарон Бертран

К вашему сведению, я подробно рассказал об этом на этой неделе: sqlperformance.com/2012/08/t-sql-queries/…
Аарон Бертран
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.