2012-06-19 3 views
15

Моя компания проклята симбиотическим партнерством, превращенным в паразитическое. Чтобы получить данные от паразита, мы должны использовать очень медленное соединение odbc. Недавно я заметил, что я могу получить большую пропускную способность, параллельно выполняя запросы (даже в одной таблице).Самый быстрый способ вставить параллельно одной таблице

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

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

EDIT: У меня есть отличная обратная связь здесь, но я думаю, что я не совсем понял, что я вытаскиваю данные через связанный сервер (который использует драйверы odbc). Другими словами, это означает, что я могу запускать обычные инструкции INSERT, и я считаю, что это обеспечило бы лучшую производительность, чем SqlBulkCopy или BULK INSERT (на самом деле, я не считаю, что BULK INSERT будет даже вариантом).

+0

Как вы предположили, параллельная запись, вероятно, не поможет производительности. Вы можете найти некоторые ответы здесь http://stackoverflow.com/questions/2861944/how-do-i-do-very-fast-inserts-to-sql-server-2008 –

+0

Вы переносите данные? Я спрашиваю, потому что вы указали свои движущиеся данные на локальные таблицы. Также как вы делаете это в коде, например, C# или как часть задания sql? –

+0

@mouters Да, но новые данные не поступают в нашу базу данных, поэтому мне придется копировать что-нибудь новое на ежедневной основе. До сих пор я делал это в ssms вручную, но параллельная идея будет сделана в C#, если я это сделаю. Вероятно, я не собираюсь делать это параллельно b/c. Теперь я получил все исторические данные и на самом деле просто нужно настроить работу sql для запуска и получения новых данных в ночное время. Но я просто хотел получить некоторую информацию об идее b/c, которую я могу использовать для нее в ближайшем будущем на других материалах. –

ответ

12

Ты прочитал (а) Load 1TB in less than 1 hour?

  1. Run как многие процессы загрузки, как у вас есть доступные процессоры. Если у вас есть 32 процессора, запустите 32 параллельных нагрузки. Если у вас 8 процессоров, запустите 8 параллельных загрузок.
  2. Если у вас есть контроль над созданием ваших входных файлов, сделайте их размера, который равномерно делится на количество потоков нагрузки, которые вы хотите запускать параллельно. Также убедитесь, что все записи принадлежат одному разделу , если вы хотите использовать стратегию раздела коммутатора.
  3. Используйте BULK-вставку вместо BCP, если вы запускаете процесс на машине SQL Server .
  4. Используйте разбиение таблиц, чтобы получить еще 8-10%, но только если ваш вход файлов ГАРАНТИРОВАН, чтобы соответствовать вашей функции секционирования, то есть , что все записи в одном файле должны находиться в одном разделе.
  5. Используйте TABLOCK, чтобы избежать блокировки при блокировке по времени.
  6. Используйте ROWS PER BATCH = 2500, или что-то рядом с этим, если вы используете , импортируя несколько потоков в один стол.

Для SQL Server 2008, есть определенные обстоятельства, при которых вы можете использовать minimal logging for a standard INSERT SELECT:

SQL Server 2008 улучшает методы, которые он может обрабатывать с минимальным лесозаготовок. Он поддерживает минимально зарегистрированные регулярные инструкции INSERT SELECT . Кроме того, включение флажка трассировки 610 позволяет SQL Server 2008 поддерживать минимальное ведение журнала против непустого B-дерева для нового ключа диапазонов, которые вызывают выделение новых страниц.

+0

Спасибо, это хорошо, но на самом деле не применяется (кроме # 1) к моей ситуации, потому что я не загружаю данные из файла, а с связанного сервера с помощью драйверов odbc ... поэтому я выполняю регулярные инструкции вставки на основе набора так или иначе. Так что я задаюсь вопросом, как я буду делать эквивалент настройки ROWS PER BATCH на нормальном вставке или если я могу? –

+0

Используете ли вы SQL Server 2008 или выше? При определенных обстоятельствах поддерживается минимальное ведение журнала в стандартных операциях INSERT SELECT. – 8kb

3

Если вы ищете, чтобы сделать это в коде, т.е. C# есть возможность использовать SqlBulkCopy (в пространстве имен System.Data.SqlClient) и как эта статья говорит о его возможности сделать это параллельно.

http://www.adathedev.co.uk/2011/01/sqlbulkcopy-to-sql-server-in-parallel.html

+0

Единственное, что плохо о том, чтобы делать что-либо навалом, - это то, что вам придется перестраивать ваши индексы после этого, так как он игнорирует их на вставке. – SQLMason

+0

Ну, я просто думал использовать C# для управления распараллеливанием. Я не думаю, что использование SqlBulkCopy было бы быстрее, чем использование SqlCommand.ExecuteNonQuery() для выдачи одного и того же набора инструкций insert, которые я сделал бы непосредственно из SSMS, не так ли? Я думаю, что одна вещь, на которую отвечают люди, забывает, что это происходит не из плоского файла ... У меня есть доступ для запуска регулярных операторов вставки непосредственно по исходным данным. –

+0

Я предполагаю, что, когда вы говорите, что это «тот же самый набор, основанный на вставке», вы имеете в виду, что вы можете сделать перекрестное соединение базы данных? Также вы пытаетесь вставить в источник также, или вы просто имеете в виду, что у вас есть доступ для чтения/записи к исходной базе данных (но в основном не имеет значения, что вы пытаетесь сделать здесь)? –

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