1

我有一个 ASP.NET 应用程序,它采用存储在 XML 中的一堆数据集并将它们扩展为 SQL,在扩展过程中它执行大量插入。

这些插入需要相当长的时间,现在我要公开承认我的 SQL 技能不是很好,所以我的诊断方法可能看起来有点粗糙。

在 SQL Server Management Activity Monitor 上,处理器时间大约为 3%,服务器上的实际 CPU 使用率也在这个范围内,因此代码没有完全运行,有 0 个等待任务,并且 I/O 稳定0.3MB/秒,批处理请求大约 180/秒

在资源等待中,Logging 的等待时间约为 900 毫秒,这导致我转向慢速磁盘,我将日志文件移动到另一组主轴,这将我的批处理请求增加到 260/秒,但它肯定不是全力以赴。

我是否认为它的磁盘导致了这个盒子的缓慢并且除了新服务器(它是一个带有 UW320 磁盘的旧 HP DL385 双 CPU)之外,一切基本上都在耐心等待它打开磁盘有没有办法加快插入速度?

4

2 回答 2

2

对于 SQL Server 的大量插入,您确实应该根据SqlBulkCopy您的要求使用。

这是一个小例子。

// Set up your target fields and types
Dictionary<string, string> uploadFields = new Dictionary<string, string>()
{
    { "LocationId", "System.Int32" },
    { "CalendarDate", "System.DateTime" },
    { "IsWorkingDay", "System.Boolean" },
    { "SnapshotDate", "System.DateTime" }
};

// Set up a DataTable to hold the stuff we want to send.
DataTable   massUpdate  = new DataTable();

// Use the dictionary above to set up columns
uploadFields
  .Keys
  .ToList()
  .ForEach(k => massUpdate.Columns.Add(k, Type.GetType(uploadFields[k])));

// Populate your datatable
foreach ( var thing in things )
{

   DataRow row = massUpdate.NewRow();

   row["LocationId"]       = thing.Id;
   row["CalendarDate"]     = thing.Date;
   row["IsWorkingDay"]     = thing.IsWorkingDay;
   row["SnapshotDate"]     = DateTime.UtcNow;

   massUpdate.Rows.Add(row);
}

// Finally, send the contents of the DataTable up via SqlBulkCopy.
// GetConnectionString
using (SqlConnection conn = new SqlConnection("Your connection string"))
{
  using (SqlBulkCopy copy = new SqlBulkCopy(conn))
  {
    conn.Open();

    foreach (var key in uploadFields.Keys)
    {
      copy.ColumnMappings.Add(key, key);
    }

    // Swap this table name with yoyr own.
    copy.DestinationTableName = "DestinationTableName";
    copy.WriteToServer(massUpdate);
    conn.Close();
  }
}

文件:-

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx

于 2012-11-15T09:02:59.083 回答
0

不完全熟悉您所处的环境,但可以进行交易吗?如果是这样,您可以通过首先启动事务,然后执行一堆 INSERT,然后结束事务来大大加快 INSERT。否则,每个 INSERT 都作为自己的事务运行,因此围绕它进行大量处理只是为了完成它。

于 2012-11-14T10:37:05.493 回答