从c#到SQL Server的批量插入策略
在我们当前的项目中,客户将向我们的系统发送复杂/嵌套消息的集合。这些信息的频率约为1000-2000 msg/秒 这些复杂对象包含事务数据(要添加)以及主数据(如果找不到,将添加主数据)。但客户传递的不是主数据的ID,而是“名称”列 系统检查这些名称是否存在主数据。如果找到,它将使用数据库中的ID,否则首先创建此主数据,然后使用这些ID 解析主数据ID后,系统将事务数据插入SQL Server数据库(使用主数据ID)。每条消息的主实体数约为15-20 以下是我们可以采取的一些策略从c#到SQL Server的批量插入策略,c#,sql-server,bulkinsert,sqlbulkcopy,C#,Sql Server,Bulkinsert,Sqlbulkcopy,在我们当前的项目中,客户将向我们的系统发送复杂/嵌套消息的集合。这些信息的频率约为1000-2000 msg/秒 这些复杂对象包含事务数据(要添加)以及主数据(如果找不到,将添加主数据)。但客户传递的不是主数据的ID,而是“名称”列 系统检查这些名称是否存在主数据。如果找到,它将使用数据库中的ID,否则首先创建此主数据,然后使用这些ID 解析主数据ID后,系统将事务数据插入SQL Server数据库(使用主数据ID)。每条消息的主实体数约为15-20 以下是我们可以采取的一些策略 我们可以首先从
SqlBulkCopy
类批量插入事务数据。我们可以点击数据库15次以获取不同实体的ID,然后再点击数据库一次以插入最终数据。我们可以使用相同的连接,在完成所有这些处理后,它将关闭因此,假设我们有1000家供应商,每个供应商发送10-15种不同产品的数据。每2-3秒,每个供应商都会向我们发送这10种产品的价格更新。他可能会开始发送有关新产品的数据,但不会非常频繁。从数据库的角度来看,没有比批量插入(例如从csv文件)更快的事情了。最好是尽快批量处理所有数据,然后使用存储过程进行处理
C层只会减慢过程,因为C层和SQL层之间的所有查询都会比SQL Server直接处理的查询慢数千倍。您最好还是使用您的#2想法(即,使用多个TVP一次性将所有15-20个实体发送至DB,并作为一组多达2000条消息进行处理) 在应用层缓存主数据查找并在发送到DB之前进行翻译听起来不错,但遗漏了一些东西:
- 15-20个实体最多可以有20k条记录(这是一个相对较小的数字,特别是考虑到非聚集索引只需要两个字段:
和Name
,当使用100%填充因子时,这两个字段可以将多行打包到单个数据页中)ID
- 并非所有20k条目都是“活动”或“当前”的,因此您不必担心缓存所有条目。因此,无论当前值是什么,都将很容易识别为被查询的值,而那些数据页(可能包括一些非活动条目,但没有什么大不了的)将被缓存在缓冲池中
ID
更新的Name
)而强制任何密钥过期或重新加载,因为这是自然处理的
是的,内存缓存是一项非常好的技术,可以极大地加快网站的速度,但这些场景/用例是针对非数据库进程在纯只读目的下一遍又一遍地请求相同的数据的情况。但这种特定场景中,数据被合并,查找值列表可能会频繁更改(更多的是由于新条目而不是由于更新条目)
总而言之,选项2是一条可行之路。我已经多次使用这种技术并取得了很大的成功,尽管没有使用15个TVP。可能需要进行一些优化/调整