Удалить все / Массовая вставка - PullRequest
6 голосов
/ 26 октября 2010

Прежде всего позвольте мне сказать, что я работаю на SQL Server 2005, поэтому у меня нет доступа к MERGE.

У меня есть таблица с ~ 150 тыс. Строк, которые я ежедневно обновляю из текстового файла.,Поскольку строки выпадают из текстового файла, мне нужно удалить их из базы данных, и если они меняются или являются новыми, мне нужно соответствующим образом обновить / вставить.

После некоторого тестирования я обнаружил, что с точки зрения производительности это экспоненциальнобыстрее выполнить полное удаление, а затем выполнить массовую вставку из текстового файла, а не читать строку за строкой, выполняя обновление / вставку.Однако недавно я наткнулся на некоторые посты, в которых обсуждается подражание функциональности MERGE SQL Server 2008 с использованием временной таблицы и вывод оператора UPDATE.

Меня это заинтересовало, потому что я смотрю на то, какМожно исключить время в моем методе Delete / Bulk Insert, когда в таблице нет строк.Я все еще думаю, что этот метод будет самым быстрым, поэтому я ищу лучший способ решить проблему с пустыми таблицами.

Спасибо

Ответы [ 5 ]

5 голосов
/ 26 октября 2010

Я думаю, что вашим самым быстрым способом было бы:

  1. Удаление всех внешних ключей и индексов из вашей таблицы.
  2. Усечение таблицы.
  3. Массовая вставка ваших данных.
  4. Воссоздание ваших внешних ключей и индексов.
3 голосов
/ 26 октября 2010

Является ли проблема в том, что решение Джо недостаточно быстрое или что вы не можете выполнять какие-либо действия с целевой таблицей во время работы вашего процесса?Если вам просто нужно запретить пользователям запускать запросы к вашей целевой таблице, вы должны поместить свой процесс в блок транзакции.Таким образом, когда ваш TRUNCATE TABLE выполняется, он создаст блокировку таблицы, которая будет удерживаться на протяжении транзакции, например:

begin tran;

truncate table stage_table

bulk insert stage_table
from N'C:\datafile.txt'

commit tran;
1 голос
/ 28 октября 2010

Существует способ обновить таблицу с нулевым временем простоя: сохранить данные за два дня в таблице и удалить старые строки после загрузки новых!

  1. Добавьте столбец DataDate, представляющий дату, для которой допустимы строки ~ 150K.
  2. Создание таблицы из одной строки и одного столбца с «сегодняшней» датой данных.
  3. Создание представления двух таблиц, в котором выбираются только строки, соответствующие строке в таблице DataDate. Индексируйте это, если хотите. Читатели теперь будут ссылаться на это представление, а не на таблицу.
  4. Массовая вставка строк. (Очевидно, вам необходимо добавить DataDate в каждую строку.)
  5. Обновить таблицу DataDate. Просмотр обновлений Мгновенно !
  6. Удаляйте вчерашние строки на досуге.

SELECT производительность не пострадает; объединение одной строки в 150000 строк по первичному ключу не должно представлять проблем для любого сервера младше 15 лет.

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

1 голос
/ 27 октября 2010

Альтернативное решение, которое удовлетворило бы ваше требование отсутствия "времени простоя" для таблицы, которую вы обновляете.

Звучит так, будто изначально вы читали файл и делали INSERT / UPDATE / DELETE по 1 строке за раз. Более эффективный подход, чем тот, который не включает в себя очистку таблицы, выглядит следующим образом:

1) массовая загрузка файла в новую отдельную таблицу (без индексов)
2) затем создайте на нем ПК
3) Выполните 3 оператора, чтобы обновить исходную таблицу из этой новой (временной) таблицы:
УДАЛИТЬ строки в основной таблице, которых нет в новой таблице
ОБНОВЛЕНИЕ строк в главной таблице, где есть новая строка в новой таблице
ВСТАВИТЬ строки в основную таблицу из новой таблицы, где они еще не существуют

Это будет работать лучше, чем ряд за строкой, и, надеюсь, должно удовлетворить ваши общие требования

0 голосов
/ 26 октября 2010

Для грубой скорости, я думаю, с ~ 150К строк в таблице, я бы просто отбросил таблицу, воссоздал ее с нуля (без индексов), а затем снова загрузил ее. После выполнения массовой загрузки создайте индексы.

Это, конечно, предполагает, что наличие периода времени, когда таблица пуста / не существует, является приемлемым, что может показаться, что может иметь место.

...