Подтвердить что ты не робот

Как сделать очень быстрые вставки в SQL Server 2008

У меня есть проект, который включает в себя запись данных с устройства непосредственно в таблицу sql.

Я очень мало обрабатываю код перед записью на sql-сервер (кстати, 2008)

Обычно я использую метод класса ExecuteNonQuery класса sqlhelper и передаю сохраненное имя proc и список параметров, которые ожидает SP.

Это очень удобно, но мне нужен гораздо более быстрый способ сделать это.

Спасибо.

4b9b3361

Ответ 1

ExecuteNonQuery с инструкцией INSERT или даже хранимой процедурой выведет вас в тысячи вложений в секунду в Express. 4000-5000/сек легко достижимы, я знаю это на самом деле.

Обычно замедление отдельных обновлений - это время ожидания флеша журнала, и вам нужно это учитывать. Самое простое решение - просто пакетное совершение. Например. совершать каждые 1000 вставок или каждую секунду. Это заполнит страницы журнала и амортизирует затраты на оплату задержек logww во всех вставках в транзакции.

С фиксацией партии вы, вероятно, будете иметь узкое место в производительности записи журнала диска, и вы ничего не можете с этим поделать, не изменив оборудование (перейдя рейд 0 в журнал).

Если вы столкнетесь с более ранними узкими местами (маловероятными), вы можете посмотреть в операторы пакетной обработки, т.е. отправьте одну партию T-SQL с несколькими вставками. Но это редко окупается.

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

Не нужно использовать интерфейс быстрой вставки (то есть SqlBulkCopy). Используя обычные INSERTS и ExecuteNoQuery для пакетной фиксации, вы будете исчерпывать пропускную способность последовательной записи диска намного быстрее, чем необходимость развертывания массовой вставки. Массовая вставка необходима на быстрых машинах, подключенных к SAN, и вы упомянули Express, поэтому, вероятно, это не так. Существует восприятие противоположного там, но просто потому, что люди не понимают, что объемная вставка дает им пакетную фиксацию, и ее пакетная фиксация, которая развивает скорость, а не объемную вставку.

Как и при любом тестировании производительности, убедитесь, что вы устранили случайность, и предопределите базу данных и журнал, вы не хотите ударять событие db или журнала роста во время тестовых измерений или во время производства, что является sooo дилетантским.

Ответ 2

объемная вставка будет самой быстрой, так как она будет минимально зарегистрирована

.NET также имеет класс SqlBulkCopy

Ответ 3

Обычно это делается с помощью BULK INSERT. В основном, вы готовите файл, а затем выдаете инструкцию BULK INSERT, а SQL Server копирует все данные из файла в таблицу с помощью быстрого метода.

У него есть некоторые ограничения (например, нет способа делать "обновить или вставлять" тип поведения, если у вас есть, возможно, существующие строки для обновления), но если вы можете обойти их, то вряд ли вы найти что-нибудь гораздо быстрее.

Ответ 4

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

Ответ 5

Вот хороший способ вставить множество записей с использованием переменных таблицы...

... но лучше всего ограничить его 1000 записями за раз, поскольку переменные таблицы "находятся в памяти"

В этом примере я вставлю 2 записи в таблицу с тремя полями - CustID, имя, фамилия

--first create an In-Memory table variable with same structure
--you could also use a temporary table, but it would be slower

declare @MyTblVar table (CustID int, FName nvarchar(50), LName nvarchar(50))

insert into @MyTblVar values (100,'Joe','Bloggs')

insert into @MyTblVar values (101,'Mary','Smith')

Insert into MyCustomerTable

Select * from @MyTblVar

Ответ 6

Если вы имеете в виду .NET, используйте SqlBulkCopy

Ответ 7

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

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

Кроме того, вам действительно нужно рассказать нам больше о ваших требованиях.