在数据处理场景中,批量插入是提升性能的关键技术。SqlSugar提供了多种高效的批量插入方案,本文将详细介绍各种方法的适用场景和性能对比。
1. 基础批量插入方法
1.1 标准批量插入
// 基础批量插入,适合小数据量(千条以内)
var list = GetDataList(); // 获取数据列表
var result = db.Insertable(list).ExecuteCommand();
// 异步版本
var result = await db.Insertable(list).ExecuteCommandAsync();
1.2 指定插入列
// 只插入特定列,提升性能
var result = db.Insertable(list)
.InsertColumns(it => new { it.Name, it.Age, it.CreateTime })
.ExecuteCommand();
2. 高性能批量插入方案
2.1 BulkCopy 大批量插入(推荐)
// 最适合海量数据插入(万级以上)
var stopwatch = Stopwatch.StartNew();
// SQL Server版本
var result = db.Fastest<Order>().BulkCopy(list);
// MySQL版本(需要安装Pomelo.EntityFrameworkCore.MySql或使用Connector/NET)
var result = db.Fastest<Order>().MySqlBulkCopy(list);
// Oracle版本
var result = db.Fastest<Order>().OracleBulkCopy(list);
stopwatch.Stop();
Console.WriteLine($"插入{list.Count}条数据,耗时:{stopwatch.ElapsedMilliseconds}ms");
2.2 分页批量插入
public async Task<int> BatchInsertInPages<T>(List<T> dataList, int pageSize = 1000) where T : class, new()
{
if (dataList == null || dataList.Count == 0) return 0;
var totalPages = (int)Math.Ceiling(dataList.Count / (double)pageSize);
var successCount = 0;
for (int i = 0; i < totalPages; i++)
{
var pageData = dataList.Skip(i * pageSize).Take(pageSize).ToList();
try
{
var result = await db.Insertable(pageData).ExecuteCommandAsync();
successCount += result;
// 每插入一页稍作休息,避免数据库压力过大
if (i < totalPages - 1)
await Task.Delay(10);
}
catch (Exception ex)
{
// 记录错误日志,继续插入下一页
Console.WriteLine($"第{i+1}页插入失败: {ex.Message}");
}
}
return successCount;
}
3. 高级批量插入技巧
3.1 带事务的批量插入
public async Task<bool> BatchInsertWithTransaction<T>(List<T> dataList) where T : class, new()
{
try
{
db.Ado.BeginTran();
// 执行批量插入
var result = await db.Fastest<T>().BulkCopyAsync(dataList);
// 可以在这里执行其他相关操作
// await SomeOtherOperation();
db.Ado.CommitTran();
return true;
}
catch (Exception ex)
{
db.Ado.RollbackTran();
Console.WriteLine($"批量插入失败: {ex.Message}");
return false;
}
}
3.2 忽略重复数据的批量插入
// 使用INSERT IGNORE(MySQL)或MERGE(SQL Server)避免重复
public async Task<int> BatchInsertIgnoreDuplicate<T>(List<T> dataList) where T : class, new()
{
// 方法1:使用SqlSugar的插入选项
var result = await db.Insertable(dataList)
.IgnoreColumns(ignoreNullColumn: true)
.ExecuteCommandAsync();
// 方法2:自定义SQL(更高性能)
if (db.CurrentConnectionConfig.DbType == DbType.MySql)
{
// MySQL的INSERT IGNORE
var tableName = db.EntityMaintenance.GetTableName<T>();
var columns = db.EntityMaintenance.GetEntityInfo<T>().Columns
.Where(c => !c.IsIgnore && !c.IsIdentity)
.Select(c => c.DbColumnName)
.ToArray();
// 构建批量插入SQL...
}
return result;
}
4. 性能优化配置
4.1 数据库连接优化
var db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = "your-connection-string",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute,
// 批量插入相关优化配置
ConfigureExternalServices = new ConfigureExternalServices()
{
EntityService = (property, column) =>
{
// 实体配置优化
}
},
// 设置命令超时时间
MoreSettings = new ConnMoreSettings()
{
CommandTimeOut = 300 // 5分钟
}
});
// 设置批量插入参数
db.Ado.CommandTimeOut = 600; // 10分钟超时
4.2 批量插入参数调优
// 配置BulkCopy参数
var bulkCopyOptions = new BulkCopyOptions()
{
BatchSize = 50000, // 每批数据量
BulkCopyTimeout = 600, // 超时时间
EnableStreaming = true, // 启用流式处理
UseInternalTransaction = false // 使用外部事务
};
var result = db.Fastest<Order>()
.BulkCopy(list, bulkCopyOptions);
SqlSugar提供了丰富的批量插入方案,开发者应根据数据量、性能要求和数据库类型选择合适的方法:
-
千条以内:使用普通
Insertable -
千条到十万条:使用
BulkCopy系列方法 -
十万条以上:使用分页+
BulkCopy组合 -
特殊需求:结合事务、错误重试等机制
正确的批量插入策略可以显著提升应用程序的数据处理能力,特别是在数据迁移、日志记录、批量操作等场景中效果尤为明显。
2025

被折叠的 条评论
为什么被折叠?



