Быстрые вставки; Массовое копирование с реляционными данными

У меня есть большой объем постоянно поступающих данных (примерно 10 000 в минуту и ​​число их увеличивается), которые я хочу вставлять в базу данных как можно эффективнее. На данный момент я использую подготовленные операторы вставки, но думаю использовать класс SqlBulkCopy для импорта данных большими порциями.

Проблема в том, что я не вставляю в одну таблицу - элементы элемента данных вставляются в многочисленные таблицы, а их столбцы идентификаторов используются как внешние ключи в других строках, которые вставляются одновременно. Я понимаю, что массовые копии не предназначены для более сложных вставок, подобных этой, но мне интересно, стоит ли менять столбцы идентификаторов (в данном случае bigints) на столбцы uniqueidentifier. Это позволит мне сделать пару массовых копий для каждой таблицы, и, поскольку я могу определить идентификаторы перед вставкой, мне не нужно проверять что-либо вроде SCOPE_IDENTITY, что мешает мне использовать массовое копирование.

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

Спасибо.


person Barguast    schedule 17.02.2011    source источник


Ответы (2)


Похоже, вы планируете заменить «SQL назначает суррогатный ключ [столбец bigint identity ()]» на методологию «процедура подготовки данных, определяющая суррогатный ключ GUID». Другими словами, ключ будет назначен не внутри SQL, а извне SQL. Учитывая ваши объемы, если процесс генерации данных может назначать суррогатный ключ, я определенно соглашусь с этим.

Тогда возникает вопрос, должны ли вы использовать GUID или ваш процесс генерации данных может создавать автоматически увеличивающиеся целые числа? Создать такой процесс, который работает последовательно и безошибочно, сложно (одна из причин, почему вы платите $$$ за SQL Server), но компромисс в пользу меньших и более удобочитаемых ключей в базе данных может стоить того.

person Philip Kelley    schedule 17.02.2011
comment
Создать такой процесс, который работает последовательно и безошибочно, сложно. . . Верно, но если вы делаете это в одном приложении без общего доступа за пределами базы данных, это намного проще. Никаких споров, никаких условий гонки, никаких транзакций. - person Mike Sherrill 'Cat Recall'; 17.02.2011
comment
Я попробовал GUID и получил 10-кратную производительность (примерно 10 000 вставок в секунду). :) - person Barguast; 17.02.2011

uniqueidentifier, вероятно, усугубит ситуацию: разделит страницу и расширит ее. См. это

Если ваша загрузка является/может быть пакетной, одним из вариантов является:

  • вы загружаете промежуточную таблицу
  • загрузить реальные таблицы за один раз как хранимую процедуру
  • используйте уникальный идентификатор в промежуточной таблице для каждой партии

Мы имеем дело с пиками около 50 тыс. строк в секунду (и таким образом увеличиваемся). На самом деле мы используем отдельную промежуточную базу данных, чтобы избежать двойной записи в журнал транзакций)

person gbn    schedule 17.02.2011
comment
Я экспериментирую с последовательным GUID (также известным как COMB), сгенерированным на C #, который, я думаю, должен обойти проблемы с кластеризованным индексом из вашей ссылки. На первый взгляд, мне очень понравилась идея вашей промежуточной таблицы, которая, как я полагаю, предназначена для хранения строк с GUID PK, а затем переноса их в таблицу с IDENTITY PK. Однако разве это не требует выполнения большого количества INSERT, так как мне нужно получить столбец идентификаторов? Возможно, я неправильно понимаю. - person Barguast; 17.02.2011
comment
@Bargauast: мы используем GUID для идентификации одного пакета (некоторые из SQL BulkCopy, другие сгенерированы некоторыми системами управления рисками). Затем мы сбрасываем в основные таблицы кластеризованные ключи bigint. GUID — это не кластеризованный ключ, а просто способ отслеживать пакеты данных для сброса в основную таблицу. GUID по-прежнему имеет ширину 16 байтов независимо от того, последовательный он или нет, и в сумме это превышает миллиарды строк. - person gbn; 17.02.2011