1

我正在做一个项目,我们从多个来源接收数据,这些数据需要保存到我们数据库中的各种表中。

快速地。

我玩过各种方法,到目前为止我发现最快的是使用 TableValue 参数的集合,填充它们并通过相应的存储过程集合定期将它们发送到数据库。

结果相当令人满意。但是,查看磁盘使用情况(Perfmon 中的 % Idle Time),我可以看到磁盘定期“抖动”(每 13-18 秒“峰值”下降到 0%),而在 %Idle 时间之间90%左右。我尝试过改变“批量”大小,但影响不大。

  1. 我是否应该能够通过(以某种方式)在减少总体空闲时间的同时避免峰值来获得更好的吞吐量?
  2. 我应该注意哪些事情来确定尖峰发生的位置?(数据库处于简单恢复模式,并且预先设置为“大”,因此不是日志文件在增长)
  3. 奖励:我已经看到其他有关将数据“流式传输”到数据库的问题,但这似乎涉及Stream来自另一个数据库的数据(此处的最后一节)。有什么办法可以将数据“推入”其中吗?

在此处输入图像描述

4

3 回答 3

1

如前所述,将大量数据插入 SQL Server 的一种非常简单的方法是“批量插入”方法。ADO.NET 提供了一种非常简单的方法来执行此操作,而无需外部文件。这是代码

var bulkCopy = new SqlBulkCopy(myConnection);
bulkCopy.DestinationTableName = "MyTable";
bulkCopy.WriteToServer (myDataSet);

这很容易。

但是:myDataSet需要与 具有完全相同的结构MyTable,即名称、字段类型和字段顺序必须完全相同。如果没有,那么有一个解决方案。这是列映射。这更容易做到:

bulkCopy.ColumnMappings.Add("ColumnNameOfDataSet", "ColumnNameOfTable");

那还是很容易的。

但是:myDataSet需要适应记忆。如果没有,事情会变得有点棘手,因为我们需要一个IDataReader允许我们用IEnumerable.

您可能会在本文中获得所需的所有信息。

于 2013-10-09T09:13:08.380 回答
1

基于alzaimar 的回答中提到的代码,我有一个使用 IObservable 的概念证明(只是看看我是否可以)。它似乎工作正常。我只需要整理一些更整洁的代码,看看这是否真的比我已经拥有的更快。

(以下代码仅在上述文章中代码下载中的测试程序上下文中才真正有意义。)

警告:NSFW,复制/粘贴后果自负!

private static void InsertDataUsingObservableBulkCopy(IEnumerable<Person> people, 
                                                      SqlConnection connection)
{
    var sub = new Subject<Person>();

    var bulkCopy = new SqlBulkCopy(connection);
    bulkCopy.DestinationTableName = "Person";
    bulkCopy.ColumnMappings.Add("Name", "Name");
    bulkCopy.ColumnMappings.Add("DateOfBirth", "DateOfBirth");

    using(var dataReader = new ObjectDataReader<Person>(people))
    {
        var task = Task.Factory.StartNew(() =>
        {
            bulkCopy.WriteToServer(dataReader);
        });
        var stopwatch = Stopwatch.StartNew();
        foreach(var person in people) sub.OnNext(person);
        sub.OnCompleted();
        task.Wait();
        Console.WriteLine("Observable Bulk copy: {0}ms",
                           stopwatch.ElapsedMilliseconds);
    }
}
于 2013-10-10T06:17:18.967 回答
0

不知道细节很难发表评论,但是将数据导入 SQL Server 的最快方法之一是从文件中批量插入。

您可以将传入的数据写入临时文件并定期批量插入。

将数据流式传输到 SQL Server Table-Valued 参数看起来也是一个很好的快速插入解决方案,因为它们保存在内存中。在回答您的问题时,是的,您可以使用它,您只需要将数据转换为 IDataReader。有多种方法可以做到这一点,DataTable例如参见此处

如果你的磁盘是一个瓶颈,你总是可以优化你的基础设施。例如,将数据库放在 RAM 磁盘或 SSD 上。

于 2013-10-09T07:01:42.607 回答