2013-07-09 3 views
12

Я загружаю большие объемы данных из текстового файла в SQL Server. В настоящее время каждая запись вставляется (или обновляется) в отдельной транзакции, но это оставляет БД в плохом состоянии, если запись не удалась.Ограничение размера транзакции в SQL Server

Я хотел бы положить все это в одна большая сделка. В моем случае я просматриваю ~ 250 000 вставок или обновлений и, возможно, ~ 1 000 000 запросов. Текстовый файл составляет примерно 60 МБ.

Неразумно ли перевести всю операцию в одну транзакцию? Какой ограничивающий фактор?

ответ

10

Это не только неразумно делать это, но это необходимо, если вы хотите сохранить целостность, если какая-либо запись не удалась, поэтому вы получаете импорт «все или ничего», как вы заметили. 250000 вставок или обновлений не будет проблемой для SQL, но я бы посмотрел, что это за миллионы запросов. Если они не нужны для выполнения модификации данных, я бы взял их из транзакции, чтобы они не замедляли весь процесс.

Вы должны учитывать, что когда у вас есть открытая транзакция (независимо от размера), внешний вид будет происходить в таблицах, к которым он прикасается, а длительные транзакции, подобные вашей, могут вызвать блокировку у других пользователей, которые пытаются их прочитать время. Если вы ожидаете, что импорт будет большим и отнимающим много времени, и система будет находиться под нагрузкой, подумайте о том, чтобы провести весь процесс в течение ночи (или любых непиковых часов), чтобы смягчить эффект.

О размере, ограничений по конкретному размеру в SQL Server нет, они могут теоретически изменять любой объем данных без проблем. Практический предел - это действительно размер файла журнала транзакций целевой базы данных. Механизм БД хранит все временные и измененные данные в этом файле во время выполнения транзакции (поэтому он может использовать его для отката, если потребуется), поэтому этот файл будет расти в размере. Он должен иметь достаточное свободное пространство в свойствах БД и достаточно пространства HD для файла для роста. Кроме того, строка или таблица блокирует, что движок будет помещать в затронутые таблицы, потребляет память, поэтому сервер должен иметь достаточно свободной памяти для всей этой сантехники. Во всяком случае, размер 60 МБ часто слишком мал, чтобы беспокоиться об общем. 250 000 строк значительны, но не так уж и много, поэтому любой сервер с приличным размером сможет справиться с этим.

0

Ну, лично я не загружаю импортированные данные непосредственно в мои таблицы prod, и я отсеял все записи, которые не пройдут, пока я не доберусь до места загрузки. Некоторые виды ошибок полностью уничтожают импорт, а другие могут просто отправить запись в таблицу исключений, которая будет отправлена ​​обратно поставщику и исправлена ​​для следующей загрузки. Обычно у меня есть логика, которая определяет, есть ли слишком много исключений и убивает пакет.

Например, предположим, что город является полем для повторного использования в вашей базе данных и в файле, состоящем из 1 000 000 записей, у вас есть десять, у которых нет города. Вероятно, лучше всего отправить их в таблицу исключений и загрузить остальные. Но предположим, у вас есть 357 894 записей без города. Тогда вам может потребоваться провести беседу с поставщиком данных, чтобы данные были зафиксированы перед загрузкой. Это, безусловно, повлияет на prod less, если вы сможете определить, что файл не используется, прежде чем пытаться повлиять на производственные таблицы.

Кроме того, почему вы делаете эту запись за раз? Вы можете часто выполнять намного быстрее при обработке на основе набора, особенно если вам уже удалось очистить данные заранее. Теперь вам все равно придется делать партиями, но одна запись за раз может быть очень медленной.

Если вы действительно хотите отбросить все это, если какие-либо ошибки детали, да, вам нужно использовать транзакции. Если вы сделаете это в SSIS, вы можете поместить транзакции только в ту часть пакета, где вы воздействуете на таблицы prod, и не беспокоиться о них при размещении данных и очистке частей.

0

Нет проблем с выполнением операции «все или ничего», если полный откат не является проблематичным для вашего бизнеса. Фактически, одна транзакция является поведением по умолчанию для большого количества встроенных утилит для вставки.

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

3

SQL Server может обрабатывать транзакции по размеру. Мы используем одну транзакцию для массовой загрузки нескольких миллионов записей.

Самая дорогая часть операции с базой данных - это, как правило, подключение и трафик клиентского сервера. Для вставки/обновления индексирование и протоколирование также являются дорогостоящими, но вы можете уменьшить эти затраты, используя правильные методы загрузки (см. Ниже). Вы действительно хотите ограничить количество соединений и данных, передаваемых между клиентом и сервером.

С этой целью вы должны рассмотреть возможность массовой загрузки данных с использованием SSIS или C# с помощью SqlBulkCopy. После того, как вы загрузите всю нагрузку, вы можете использовать операции с множеством на сервере, чтобы обновить или проверить свои данные.

Посмотрите на этот вопрос, чтобы узнать больше о оптимизации загрузки данных. Вопрос связан с C#, но большая часть информации полезна для SSIS или других методов загрузки. What's the fastest way to bulk insert a lot of data in SQL Server (C# client).

Смежные вопросы