Использование SqlBulkInsert в рабочих приложениях

В настоящее время мы разрабатываем приложение, которое генерирует от 5 до 10 000 строк данных в конкретной таблице для каждого сеанса пользователя. В настоящее время мы используем текстовые команды sql для вставки каждой строки данных за раз, поэтому операция сохранения может занять до минуты. Мы играем с использованием SqlBulkInserts и видим, что время сократилось до менее 500 мс. Кто-нибудь возражает против использования SqlBulkInserts в рабочем приложении, где многие пользователи будут использовать систему?


person PCG    schedule 06.01.2012    source источник


Ответы (3)


Я никогда не сталкивался с проблемой SqlBulkCopy с установленным параметром tableLock и блокировкой другого пользователя из-за этого. Опция TableLock повышает эффективность вставки, о чем говорили многие люди, и простое ее использование показало мне.

Мой типичный метод:

public void Bulk(String connectionString, DataTable data, String destinationTable)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        using (SqlBulkCopy bulkCopy =
            new SqlBulkCopy
            (
            connection,
            SqlBulkCopyOptions.TableLock |
            SqlBulkCopyOptions.FireTriggers |
            SqlBulkCopyOptions.UseInternalTransaction,
            null
            ))
        {
            bulkCopy.BatchSize = data.Rows.Count;
            bulkCopy.DestinationTableName = String.Format("[{0}]", destinationTable);
            connection.Open();
            bulkCopy.WriteToServer(data);
        }
    }
}
person justinlabenne    schedule 07.01.2012

Перед реализацией с помощью SqlBulkInsert попробуйте динамически создать запрос INSERT, чтобы он выглядел следующим образом:

insert into MyTable (Column1, Column2)
select 123, 'abc'
union all
select 124, 'def'
union all
select 125, 'yyy'
union all
select 126, 'zzz'

Это будет только один вызов базы данных, который должен выполняться гораздо быстрее. Для объединения строк SQL убедитесь, что вы используете класс StringBuilder.

person D'Arcy Rittich    schedule 06.01.2012
comment
Я рассматривал эту идею, но моя проблема с этим подходом заключается в том, что мне нужно значение идентификатора, которое было создано для первичного ключа, обратно на сервер, поскольку мы строим иерархическое дерево, поскольку это самоссылающаяся таблица. - person PCG; 06.01.2012
comment
И что? Это также полностью исключает использование SqlBulkCopy - как вы выполняете массовые вставки, если вам нужен сгенерированный сервером идентификатор? Ответ правильный, ваша похвала противоречит вашему собственному утверждению. - person TomTom; 06.01.2012
comment
Ваше право, а я идиот. Что мы делаем в реализации SqlBulkCopy, так это извлекаем список данных, которые мы только что вставили на каждом уровне дерева, чтобы получить список сгенерированных идентификаторов. Я даже не думал о том, чтобы сделать то же самое, используя приведенное вами выше утверждение. - person PCG; 07.01.2012

Я думаю, что это правильный путь, если вашему приложению действительно нужно создавать столько записей за сеанс.

person Mithrandir    schedule 06.01.2012
comment
Из-за того, как структурирована наша база данных, у нас есть 12 таблиц, в которых мы сохраняем данные в одной транзакции, из-за этого мы получали ошибки взаимоблокировки при использовании SqlBulkCopy. Установив SqlBulkCopyOptions.TableLock, взаимоблокировки исчезли. Есть ли недостаток в блокировке таблицы для массовых вставок? Не повредит ли это другим пользователям, пытающимся выполнить транзакцию в то же время? - person PCG; 06.01.2012
comment
Вы имеете в виду, за исключением того, что у вас есть TABLE LOCK? затем вы приходите и ноете о блокировках таблиц ;) Взаимоблокировки - это другое дело и признак того, что ваше программирование сделано плохо - устраняйте проблемы по мере их возникновения, не кладите плохой код на плохой код, чтобы избежать симптомов. - person TomTom; 06.01.2012
comment
Я бы полностью согласился с вами, если бы менеджер по продукту не кричал мне в спину, чтобы ничего не менять в схеме базы данных, за исключением, может быть, некоторых индексов и чтобы все работало лучше. Я был совершенно взволнован всей этой ситуацией. - person PCG; 07.01.2012