You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure SQL批量插入:提速方法与降低DTU占用方案咨询

针对Azure SQL批量插入的优化方案

嘿,针对你的两个问题,我来分享下实际项目里常用的解决方案,应该能帮到你:

1. 更快的插入方法:替换循环单条插入为批量操作

你现在的循环单条插入方式,每一条都要单独和数据库建立连接、执行命令、提交小事务,这会产生大量的网络往返和数据库开销,也是DTU飙升的核心原因。推荐这几种更高效的方式:

方式一:EF的AddRange批量添加(简单易实现)

如果用的是Entity Framework,可以把所有要插入的实体先收集到列表里,再一次性调用AddRange和SaveChanges,这样EF会把多个插入合并成更少的数据库操作:

using(var db = new DBContext())
{
    var notifications = new List<UserNotification>();
    foreach(var userID in userIDs)
    {
        notifications.Add(new UserNotification
        {
            ForUserID = userID,
            Date = DateTime.Now.ToUniversalTime(),
            ForObjectID = forObjectID,
            TypeID = (byte)type,
            Count = 1,
            MetaData1 = metaData1.Value
        });
    }
    db.UserNotifications.AddRange(notifications);
    db.SaveChanges();
}

方式二:SqlBulkCopy(超大数据量下最优)

如果数据量超过10万级,SqlBulkCopy是效率最高的选择,它直接利用SQL Server的批量插入机制,能大幅减少DTU消耗:

// 先构造DataTable,结构和UserNotifications表匹配
var dt = new DataTable();
dt.Columns.Add("ForUserID", typeof(int)); // 替换成你的实际字段类型
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("ForObjectID", typeof(int));
dt.Columns.Add("TypeID", typeof(byte));
dt.Columns.Add("Count", typeof(int));
dt.Columns.Add("MetaData1", typeof(string)); // 替换成你的实际类型

foreach(var userID in userIDs)
{
    dt.Rows.Add(
        userID,
        DateTime.Now.ToUniversalTime(),
        forObjectID,
        (byte)type,
        1,
        metaData1.Value
    );
}

// 执行批量复制
using(var conn = new SqlConnection(db.Database.Connection.ConnectionString))
{
    conn.Open();
    using(var bulkCopy = new SqlBulkCopy(conn))
    {
        bulkCopy.DestinationTableName = "UserNotifications";
        // 映射列名(如果DataTable和表列名一致可以省略)
        bulkCopy.ColumnMappings.Add("ForUserID", "ForUserID");
        bulkCopy.ColumnMappings.Add("Date", "Date");
        // ... 其他列映射
        bulkCopy.WriteToServer(dt);
    }
}

方式三:表值参数(TVP)

如果需要在插入时执行一些自定义逻辑,TVP是不错的选择,它允许你把数据集作为参数传递给存储过程,再在存储过程里批量插入:

  1. 先创建用户定义表类型:
CREATE TYPE UserNotificationType AS TABLE (
    ForUserID INT,
    Date DATETIME,
    ForObjectID INT,
    TypeID TINYINT,
    Count INT,
    MetaData1 NVARCHAR(MAX) -- 替换成你的实际类型
);
  1. 创建批量插入的存储过程:
CREATE PROCEDURE BulkInsertUserNotifications
    @Notifications UserNotificationType READONLY
AS
BEGIN
    INSERT INTO UserNotifications (ForUserID, Date, ForObjectID, TypeID, Count, MetaData1)
    SELECT ForUserID, Date, ForObjectID, TypeID, Count, MetaData1 FROM @Notifications;
END
  1. C#调用代码:
using(var db = new DBContext())
{
    var dt = new DataTable();
    // 构造DataTable逻辑同SqlBulkCopy示例
    // ...

    var parameter = new SqlParameter("@Notifications", dt);
    parameter.SqlDbType = SqlDbType.Structured;
    parameter.TypeName = "UserNotificationType";
    db.Database.ExecuteSqlCommand("EXEC BulkInsertUserNotifications @Notifications", parameter);
}

2. 放缓脚本执行,避免DTU占用过高

如果不想一次性批量插入(比如担心大事务锁表),或者需要严格控制DTU使用率,可以通过分批次插入+延迟的方式来节流:

方案:分批次处理,每批插入后暂停

把10万条数据分成若干小批次(比如每批1000条),每插入一批后暂停几秒,给数据库喘息的空间:

using(var db = new DBContext())
{
    int batchSize = 1000;
    int total = userIDs.Count();
    for(int i = 0; i < total; i += batchSize)
    {
        var batchUserIDs = userIDs.Skip(i).Take(batchSize).ToList();
        var notifications = new List<UserNotification>();
        foreach(var userID in batchUserIDs)
        {
            notifications.Add(new UserNotification
            {
                ForUserID = userID,
                Date = DateTime.Now.ToUniversalTime(),
                ForObjectID = forObjectID,
                TypeID = (byte)type,
                Count = 1,
                MetaData1 = metaData1.Value
            });
        }
        db.UserNotifications.AddRange(notifications);
        db.SaveChanges();
        
        // 每批插入后暂停1秒(可根据DTU实际情况调整时长)
        System.Threading.Thread.Sleep(1000);
    }
}

进阶:动态监控DTU使用率调整速度

如果想更智能,可以通过Azure Monitor的API获取当前DTU使用率,当使用率超过阈值时延长暂停时间,低于阈值时加快速度。不过这个实现稍复杂,适合对性能控制要求极高的场景。

另外,也可以调整Azure SQL的事务隔离级别(比如开启READ COMMITTED SNAPSHOT),减少锁竞争,但这个需要结合你的业务场景评估。


内容的提问来源于stack exchange,提问作者Tom Gullen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:56:57