工作高峰时段的 Sql Server 批量插入
Posted
技术标签:
【中文标题】工作高峰时段的 Sql Server 批量插入【英文标题】:Sql Server Bulk Insert during peak operations hours 【发布时间】:2021-01-05 06:56:17 【问题描述】:我在数据库中有一个表,该表通常非常频繁地同时查询,峰值接近每秒 100 次选择(根据分析数据推测)。表中的行数很快就会达到 2 亿条记录。对单个/单个行的持续更新,也继续执行。
此表中的数据是通过夜间作业填充的,故意在凌晨 1 点非高峰时间,以免影响性能。导入大小有时可以达到 100 万条记录。使用SqlBulkCopy,如下例。
var dt = new DataTable();
dt.Columns.Add("EmployeeID");
dt.Columns.Add("Name");
for (var i = 1; i < 1000000; i++)
dt.Rows.Add(i + 1, "Name " + i + 1);
using (var sqlBulk = new SqlBulkCopy(_connectionString))
sqlBulk.DestinationTableName = "Employees";
sqlBulk.WriteToServer(dt);
最近收到源数据系统的请求,两次抽数据,白天也抽一次,有效的让我们在高峰时段插入数据。
关于如何在不影响最终用户体验的性能的情况下执行 SqlClient.SqlBulkCopy 操作的任何建议。这种场景有可扩展的解决方案吗?现有行数增加,导入大小增加和最终用户群增加,但我仍然可以在一天中的任何时间继续执行如此庞大的数据抽取。
抱歉,没有太多具体的数据点可以分享,有点含糊。只是想了解其他人是如何做到这一点的,如果有人有这样的经历的话。
【问题讨论】:
您也许可以研究分区并将临时表切换到主表:brentozar.com/archive/2012/03/… 感谢@SteveFord。分区更适合您共享的报告示例。在我的情况下,日期范围不能真正成为分区。我的数据是用户通知。需要一起获取和服务最新的和最旧的。关于临时表的方式-您能详细说明一下吗?您的意思是我们首先将批量数据存放在临时表中,然后如何将其快速移动到主表而不影响传入的选择? 即使使用分区,您也可以同时获取最新和最旧的数据。该表的访问方式与其他任何表一样,只是分区表在物理上存储为单独的表。对表的任何查询都会从所有分区并行获取数据。暂存的想法是您加载到一个看起来像分区表的暂存表中并执行 switch 语句。这使得 staging table 成为 table 的一部分,这只是改变了元数据。 其他替代方案是尝试读取已提交快照隔离,特别是如果您的加载进程是写入数据库的唯一进程。使用此设置(在 DB 级别设置)读取永远不会阻止写入并且写入永远不会阻止读取。您可能需要增加 TempDB 的大小,但如果您仍然批量插入,则不一定。 【参考方案1】:您可以小批量加载数据,这样您就不会产生大事务并消耗大量事务日志。在每批之后,您可以提交事务。您可以使用内部事务处理方法,将每个批次作为单独的事务处理。 Read more on transactions and bulkcopy
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
connectionString, SqlBulkCopyOptions.KeepIdentity |
SqlBulkCopyOptions.UseInternalTransaction))
bulkCopy.BatchSize = 10000;
bulkCopy.DestinationTableName =
"dbo.BulkCopyDemoMatchingColumns";
// Write from the source to the destination.
// This should fail with a duplicate key error
// after some of the batches have been copied.
try
bulkCopy.WriteToServer(reader);
catch (Exception ex)
Console.WriteLine(ex.Message);
finally
reader.Close();
此外,还有一些与批量复制相关的优化提示。您可以尝试在可能的情况下利用:Bulk Copy optimizations
【讨论】:
嘿@Venkataraman。谢谢。这也是我们在夜间工作中已经在做的事情。使用小批量插入。你的意思是在快速射击大量小批量,在高峰时段不会有太大影响? @techrookie,是的。小批量并经常提交它们,将避免内存压力和事务日志压力。我们之前尝试过小批量,这减少了主表的阻塞。以上是关于工作高峰时段的 Sql Server 批量插入的主要内容,如果未能解决你的问题,请参考以下文章