2013-05-29 2 views
1

У меня есть две таблицы, где иногда приходится добавлять много строк. Последний случай составлял 800000 строк в таблице1 и в 3 раза больше в таблице 2.Скорость вставки MS SQL Server с использованием SqlCommand

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

CREATE PROCEDURE dbo.AddOrderBookEntry 
@Moment datetime, 
@LocalTime datetime, 
@BB decimal(18,4), 
@BO decimal(18,4), 
@QBB float, 
@QBO float, 
@SumTr float = NULL, 
@QSumTr float = NULL, 
@IV float = NULL, 
@InstrumentId bigint, 
@AverageValues Averages READONLY 
AS 
BEGIN 
INSERT INTO dbo.OrderBook 
VALUES (@Moment,@LocalTime,@BB,@BO,@QBB,@QBO,@SumTr,@QSumTr,@IV,@InstrumentId) 

DECLARE @OBID bigint 
SELECT @OBID = SCOPE_IDENTITY() 

INSERT INTO dbo.OrderbookAverages 
select N, BN, [ON], @OBID from @AverageValues 

END 
GO 

Это работает, но меня беспокоит скорость. Согласно моим мерам, для записи нужно принять 1,75 миллисекунды. Я измеряю скорость из приложения .net, которое записывает данные в db. Это приложение находится на том же компьютере, что и SQL Server.

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

+0

То, что я вижу в вашем примере вы выполняете прок для каждой записи, но вы получите более высокую производительность, если вы инвестируете в вашей инфраструктуре реорганизации. INSERT от SELECT будет работать быстрее, чем отдельные вставки –

+0

Не могли бы вы рассказать? Вы имеете в виду пользовательский тип OrderBookEntry, который позволит передать набор параметров в качестве параметра? – athabaska

ответ

1

Около 20 минут для 800 000 записей не очень быстро, но только вы можете решить, достаточно ли он достаточно.

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

Это, вероятно, будет намного быстрее, но вы должны подумать, стоит ли тратить время. Как часто вы запускаете эти импорт, например? Если вы делаете их пять раз в день, то любое ускорение будет стоить того. Если вы делаете их один раз в месяц, то, вероятно, не :-)

+0

В большинстве случаев это приложение работает с довольно тонким потоком данных, но иногда аналитики хотят загружать данные предыдущих дней, а затем его не круто. Но я в основном думал, что может быть что-то, что мне не хватает (у меня был довольно длинный перерыв с момента последнего программирования db), например, например, «О, используйте инфраструктуру сущности, ее 1000 раз быстрее, чем« – athabaska

+0

И мы довольно жестко на диске, а guid будет больше, чем bigint, правильно? – athabaska

+0

Нет, EF не волшебным образом сделает это быстрее. Это предложение хорошее, сделайте массовую вставку родительской, навалом вставьте потомки в временную таблицу, затем присоедините их к родительскому, чтобы получить право FK. – BlackICE

0

Часто необходимо отправить очень большое количество строк из бизнес-кода в базу данных. Существует несколько способов сделать это:

Вызов операторов вставки строки за один раз для всех данных Сериализуйте данные в некоторый формат (CSV или XML), отправьте его в хранимую процедуру в виде большой строки , unserialize строку в хранимой процедуре TSQL и сделать вставку. Сохраните данные в формате плоского файла на сервере базы данных. Запустите пакет DTS или прочитайте файл. SqlBulkCopy!

Каждый раз, когда я обнаружил SqlBulkCopy, мне понравилось. MS SQL Server включает в себя популярную команду bcp для перемещения данных из одной таблицы в другую на одном сервере или между серверами. SqlBulkCopy - это класс, который обеспечивает аналогичную функциональность.

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

Как это просто использовать. В этом примере у нас есть функция, которая пишет копии DataTable в таблицу базы данных MS SQL, называемую «tblFooBar».

using System.Data.SqlClient; 
… 

Function WriteToDB(DataTable dt) 

{ 

    SqlBulkCopy sqlBC = new SqlBulkCopy(dbconnectionstring); 

    sqlBC.BatchSize = 25000; 

    sqlBC.BulkCopyTimeout = 60; 

    sqlBC.DestinationTableName = “dbo.tblFooBar” ; 

    sqlBC.WriteToServer(dt); 

} 
… 

Ссылка MSDN является:

Link for the details of bulk insert

+0

Я думал о массовой вставке, но мне придется найти идентификаторы вставленных строк. Учитывая, что может быть множество приложений для писателей, это было бы грязным имхо. – athabaska

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