asp.net - 减慢批量插入的执行速度
问题描述
我们有一个位于 S1 定价层的 Azure SQL 数据库。我们的站点被大量缓存,因此数据库命中率绝对是最低的。平均 DTU 使用率仅为约 1.5%,这非常好,因为我们的数据库成本只是我们旧网站上的一小部分(20 英镑/月对 400 英镑/月!)
然而,在网站上,我们确实有需要插入大约 10 万条记录的小脚本(用户执行操作时的通知,例如创建新教程)。
触发此操作后,DTU 会在 3-5 分钟内达到 100% 峰值。
该脚本只是一个调用插入的循环:
using(var db = new DBContext())
{
foreach(var userID in userIDs)
{
db.ExecuteCommand(
"INSERT INTO UserNotifications " +
"(ForUserID, Date, ForObjectTypeID, ForObjectID, TypeID, Count, MetaData1)
VALUES ({0}, {1}, NULL, {2}, {3}, {4}, {5}, {6})",
userID, DateTime.Now.ToUniversalTime(), forObjectID, (byte)type, 1, metaData1.Value
);
}
}
- 有没有比这更快的插入方法?
- 此外,减慢此脚本执行速度的最佳方法是什么,以便 DTU 的使用不会阻塞所有内容?
解决方案
您每次插入一行 - 这效率不高。
TVP类似于反向数据读取器,并且效率很高。
较低的技术是一次插入 900 行(最多 1000 行)。仅此一项就可能效率高出 400 倍。
StringBuilder sb = new StringBuilder();
string insert = "INSERT INTO UserNotifications " +
"(ForUserID, Date, ForObjectTypeID, ForObjectID, TypeID, Count, MetaData1) " +
"VALUES ";
sb.AppendLine(insert);
int count = 0;
using(var db = new DBContext())
{
foreach(var userID in userIDs)
{
sb.AppendLine(string.Format(({0}, {1}, NULL, {2}, {3}, {4}, {5}, {6}), ",
userID, DateTime.Now.ToUniversalTime(), forObjectID, (byte)type, 1, metaData1.Value);
count++;
if (count = 990)
{
db.ExecuteCommand(sb.ToString());
count = 0;
sb.Clear();
sb.AppendLine(insert);
//can sleep here to throttle down cpu
}
}
if (count > 0)
{
db.ExecuteCommand(sb.ToString());
}
}
推荐阅读
- java - Junit 5.5.1 和 5.5.2 突然无法运行测试:“进程以退出代码 -1 完成”;5.6.0-RC1 缺少一个类
- vb.net - 更新后VS中的TextBox错误
- numpy - Numpy 和 Scipy 中稀疏矩阵的选择
- pytest - 显示 pytest 语法警告
- c# - 如何通过从数据库中选择 C# 中的组合框来获得前 3 个值
- c++ - C++:将 lambda 作为带有模板参数的函数传递会使推导模板类型失败
- python-3.x - 使用 np.arange 和幂运算符 ** 计算 2 的前 30 次幂,从 2^0 开始
- highcharts - Highcharts 饼图注释未居中
- c# - 将 .NET Core webapp 项目从 .net core 2.2 迁移到 3.1 后,它无法与 Azure 中基于 VM 的远程应用建立套接字连接
- c# - DirectorySearcher 异步使用 await