如何确保将数据插入到 SQL Server 2008 R2 时首先缓存在内存中?

想象一条数据流是“突发性”的,也就是说可能会有10,000个事件在很短的时间内到达,然后接下来的一分钟内什么都没有。

enter image description here

您的专家建议:我如何编写C#插入代码以确保SQL Server立即将所有内容缓存到自己的RAM中,而不会阻塞我的应用程序超过将数据输入到该RAM所需的时间?为了实现这一目标,您是否知道设置SQL服务器本身或设置我要写入的各个SQL表的任何模式? 当然,我可以做自己的版本,其中包括在RAM中构建自己的队列 - 但我不想重新发明旧石器时代的石斧,可以这么说。

1你是在说C#客户端代码吗?所以你对确保写入被缓存的SQL代码感兴趣? - Richard
6我倾向于自己排队插入,即使关系数据库管理系统支持它,因为:(a)这并不难,(b)完全在你的控制之下,(c)它不依赖于供应商。 - corlettk
我对包含SQL代码以确保写入被缓存的C#客户端代码很感兴趣。不过,我相信我可以使用纯T-SQL并编写自己的C#封装器来完成工作。 - Gravitas
3个回答

你试过只写入并看看会发生什么吗?你有已知的瓶颈吗?

如果你需要防止应用被阻塞,一种方法是将写入操作排队,延迟数据库调用。然而,我预计队列会在一两秒钟内清空:所以如果这样可以的话,你需要一个队列吗?

或者你可以将数据暂存在一个暂存表中,然后稍后进行刷新?我们使用这种技术来处理每分钟数百万行的持续写入(实际上我们使用带简单恢复模式的暂存数据库),但在只写入行的经验积累之前,我们没有实施它。

注意:SQL Server 中的每次写入都将作为事务日志(WAL)协议的一部分写入磁盘。这适用于该写入的 t-log 条目。

包含该行的数据页将在某个时间点上写入磁盘(基于时间、使用情况、内存压力等),但通常情况下,你的数据已经在内存中了。这称为“检查点”操作,它不会从内存中驱逐数据,只是刷新更改(编辑于2011年11月24日)

编辑:

根据上面的最后一段,出于全面考虑,请将此数据库的LDF转移到专用磁盘组以获得更高的性能。同样适用于暂存数据库(每个MDF/LDF各一个)。对于数据库服务器来说,通常有12个或3个不同的卷(通常通过SAN实现)。

1将数据暂存在一个中间表是可能是最好的方式。我还从我的一个朋友那里得到了确认,他在一个拥有数十亿行数据的环境中工作,他说他使用临时表进行更快速的分析。 - Gravitas

除非我漏掉了什么,否则这将违反ACID(http://en.wikipedia.org/wiki/ACID)的持久性要求。也就是说,如果您的应用程序将数据“写入”到RAM,然后服务器崩溃,您的数据将丢失。 因此,您所寻求的要么是一个非数据库系统,用作最终存储到数据库的队列,要么是一个足够快速的数据库系统来满足您的需求。我建议先尝试后者,看看是否足够;不要自找麻烦。

我曾经使用过一个数据集来做这个。当行到达时,我将它们插入到数据集中,然后另一个线程每隔大约2秒钟将这些行刷新到数据库中。你也可以使用XML文档来进行缓存,然后一次性将XML传递给数据库,这可能会更好。 祝好, Piotr