Самый быстрый способ вставить параллельно одной таблице
Моя компания проклята симбиотическим партнерством, превратившимся в паразитическую. Чтобы получить данные от паразита, мы должны использовать очень медленное соединение odbc. Недавно я заметил, что я могу получить большую пропускную способность, параллельно выполняя запросы (даже в одной таблице).
Существует очень большая таблица, в которой я хочу извлечь данные и переместить их в нашу локальную таблицу. Выполняя запросы параллельно, я могу получить данные быстрее, но я также предполагаю, что это может вызвать проблемы при попытке записи данных из нескольких запросов в одну и ту же таблицу сразу.
Какой совет вы можете дать мне о том, как лучше всего справиться с этой ситуацией, чтобы я мог использовать увеличенную скорость использования запросов параллельно?
EDIT: Я получил отличные отзывы здесь, но я думаю, что я не совсем понял, что я вытаскиваю данные через связанный сервер (который использует драйверы odbc). Другими словами, это означает, что я могу запускать обычные инструкции INSERT, и я считаю, что это обеспечит лучшую производительность, чем SqlBulkCopy или BULK INSERT (на самом деле, я не верю, что BULK INSERT будет даже вариантом).
Ответы
Ответ 1
Вы читали Загрузить 1TB менее чем за 1 час?
- Запустите столько загрузочных процессов, сколько у вас есть. Если у вас есть 32 CPU, запускайте 32 параллельных нагрузки. Если у вас 8 процессоров, запустите 8 параллельных грузы.
- Если у вас есть контроль над созданием ваших входных файлов, сделайте их размера, который равномерно делится на количество потоков нагрузки, которые вы хотите работать параллельно. Также убедитесь, что все записи принадлежат одному раздел, если вы хотите использовать стратегию разделения коммутатора.
- Используйте BULK insert вместо BCP, если вы запускаете процесс на SQL Server.
- Используйте разбиение таблиц, чтобы получить еще 8-10%, но только если ваш вход файлы ГАРАНТИРОВАНЫ, чтобы соответствовать вашей функции секционирования, что означает что все записи в одном файле должны находиться в одном разделе.
- Используйте TABLOCK, чтобы избежать блокировки по времени.
- Используйте ROWS PER BATCH = 2500, или что-то рядом с этим, если вы импортируя несколько потоков в одну таблицу.
Для SQL Server 2008 существуют определенные обстоятельства, при которых вы можете использовать минимальное ведение журнала для стандартного INSERT SELECT:
SQL Server 2008 улучшает методы, с которыми он может работать с минимальными Ведение журнала. Он поддерживает минимально зарегистрированный регулярный INSERT SELECT заявления. Кроме того, включение флажка трассировки 610 позволяет SQL Server 2008 поддержка минимального ведения журнала против непустого B-дерева для нового ключа диапазоны, которые вызывают выделение новых страниц.
Ответ 2
Если вы хотите сделать это в коде, то есть С#, есть возможность использовать SqlBulkCopy
(в пространстве имен System.Data.SqlClient), и в этой статье предлагается сделать это параллельно.
http://www.adathedev.co.uk/2011/01/sqlbulkcopy-to-sql-server-in-parallel.html
Ответ 3
Если вы обновили до SQL 2014, вы можете вставить его параллельно (уровень совместимости должен быть 110). Видеть это:
http://msdn.microsoft.com/en-us/library/bb510411%28v=sql.120%29.aspx