将数千行数据插入 Azure SQL 数据库的最高效方法?
Most performant way to insert thousands of rows of data into Azure SQL DB?
我正在开发一个导入器,它生成需要进入 Azure SQL 数据库(配置为具有 4 个 vCore 的无服务器)的数据。
我插入的对象只有几列
Id : INT
Type : NVARCHAR
Uid : NVARCHAR
Json : NVARCHAR
Json
数据的平均大小约为 1.5kb。我每个 运行.
导入大约 300 万行
我目前的方法是每插入 2000 行使用一个事务(下面的代码摘录):
using var transaction = sqlConnection.BeginTransaction (System.Data.IsolationLevel.ReadUncommitted);
cmd = new SqlCommand (insertNodeQuery, sqlConnection) {
CommandTimeout = 600
};
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue ("@Type", node.Type);
[...]
var insertTask = cmd.ExecuteNonQueryAsync ();
tasks.Add (insertTask);
然后我用Task.WhenAll(tasks)
等待交易完成
在我的 PC 上,相对于 (localdb)
,这让我每秒插入 20 次。但是,对于 Azure DB,我每秒只能看到大约 5 次插入。我知道,这涉及到网络延迟,但即使 运行 在同一区域的 Azure 数据中心 (AKS) 中运行代码,我也没有接近本地数据库的速度。
这让我想知道是否有更好的 运行 导入方式?如果我将生成的内存中数据发送到数据库,SqlBulkCopy
会是一个选项吗?
我还能如何优化性能?
How else can I optimize the performance?
SqlBulkCopy 是最好的。您可以加载 DataTable 以加载 in-memory 数据,或使用像 this 这样的适配器将 in-memory 对象的集合转换为 IDataReader 以与 SqlBulkCopy 一起使用。
您还可以将每个批次作为 JSON 文档作为参数发送到 SQL 查询,您可以在其中使用 OPENJSON.
读取它
这两个都应该比 single-row 插入更快。
Client-side 加载方法(大致)从最慢到最快的顺序是:
- single-row 插入,无事务
- single-row 插入,事务
- single-row 使用 TSQL 批处理插入
- single-row 使用 TDS 批处理插入 (SqlDataAdapter)
- 使用 XML 或 JSON
批量插入
- 批量插入Table-valued个参数
- 使用 SqlBulkCopy 批量插入
我正在开发一个导入器,它生成需要进入 Azure SQL 数据库(配置为具有 4 个 vCore 的无服务器)的数据。
我插入的对象只有几列
Id : INT
Type : NVARCHAR
Uid : NVARCHAR
Json : NVARCHAR
Json
数据的平均大小约为 1.5kb。我每个 运行.
我目前的方法是每插入 2000 行使用一个事务(下面的代码摘录):
using var transaction = sqlConnection.BeginTransaction (System.Data.IsolationLevel.ReadUncommitted);
cmd = new SqlCommand (insertNodeQuery, sqlConnection) {
CommandTimeout = 600
};
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue ("@Type", node.Type);
[...]
var insertTask = cmd.ExecuteNonQueryAsync ();
tasks.Add (insertTask);
然后我用Task.WhenAll(tasks)
等待交易完成
在我的 PC 上,相对于 (localdb)
,这让我每秒插入 20 次。但是,对于 Azure DB,我每秒只能看到大约 5 次插入。我知道,这涉及到网络延迟,但即使 运行 在同一区域的 Azure 数据中心 (AKS) 中运行代码,我也没有接近本地数据库的速度。
这让我想知道是否有更好的 运行 导入方式?如果我将生成的内存中数据发送到数据库,SqlBulkCopy
会是一个选项吗?
我还能如何优化性能?
How else can I optimize the performance?
SqlBulkCopy 是最好的。您可以加载 DataTable 以加载 in-memory 数据,或使用像 this 这样的适配器将 in-memory 对象的集合转换为 IDataReader 以与 SqlBulkCopy 一起使用。
您还可以将每个批次作为 JSON 文档作为参数发送到 SQL 查询,您可以在其中使用 OPENJSON.
读取它这两个都应该比 single-row 插入更快。
Client-side 加载方法(大致)从最慢到最快的顺序是:
- single-row 插入,无事务
- single-row 插入,事务
- single-row 使用 TSQL 批处理插入
- single-row 使用 TDS 批处理插入 (SqlDataAdapter)
- 使用 XML 或 JSON 批量插入
- 批量插入Table-valued个参数
- 使用 SqlBulkCopy 批量插入