1

I have two tables where I have to add a lot of rows sometimes. Last case was 800000 rows into table1, and 3 times more into table 2.

I use following stored procedure to insert rows, because I don't see way to use bulk copy, considering tables have auto id fields and have a foreign key relation.

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

It works, but what bothers me is speed. According to my measures, it takes app 1.75 milliseconds for a record to be added. I am measuring speed from .net application that writes data into db. This application is on the same computer as SQL Server.

So question is - is this speed okeyish for the approach I use? Or it can be improved?

4

2 回答 2

1

800.000 条记录大约 20 分钟并不是很快,但只有您可以决定它是否足够快。

您可以通过两步过程摆脱使用批量插入的问题。首先使用批量插入将数据加载到两个表中,然后通过某种方式从第一个表中查找自动 ID 来连接它们。也许通过为匹配的行分配一个您预先生成的 id(一个 guid 可能工作)。

这可能会快得多,但您必须考虑是否值得花时间。例如,您多久运行一次这些导入?如果你每天做五次,那么任何加速都是值得的。如果你每个月都做一次,那么可能不会:-)

于 2013-05-29T07:24:11.090 回答
0

通常需要将大量行从业务代码发送到数据库。有很多方法可以做到这一点:

为整个数据一次调用一行插入语句将数据序列化为某种平面格式(CSV 或 XML),将其作为大字符串发送到存储过程,在存储过程 TSQL 中反序列化字符串并执行插入。将数据保存为数据库服务器上的平面文件格式。运行 DTS 包或喜欢阅读文件。SqlBulkCopy!

自从我发现 SqlBulkCopy 以来,我一直很喜欢它。MS SQL Server 包含一个名为 bcp 的流行命令,用于在一台服务器或服务器之间将数据从一个表移动到另一个表。SqlBulkCopy 是一个提供类似功能的类。

SqlBulkCopy 比多个插入语句、序列化/反序列化数据或将数据保存到文件系统并运行导入要快得多。它对您可以发送的数据也没有限制,并且在处理插入时非常有效。

这就是使用它的简单程度。在示例中,我们有一个函数将 DataTable 副本写入名为“tblFooBar”的 MS SQL 数据库表中。

 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 链接是:

批量插入详细信息的链接

于 2013-05-29T07:32:16.947 回答