Wcf 从内存插入和查询数据的最佳实践

Wcf 从内存插入和查询数据的最佳实践,wcf,in-memory-database,Wcf,In Memory Database,我们有一个应用程序,它获取实时数据并将其插入数据库。它每天在线4.5小时。我们在17个表中每秒插入数据。用户可以在任何时候查询任何表格,以获取最新的第二次数据和历史记录 使用C#控制台应用程序处理提要和插入 通过WCF服务处理用户请求 我们发现插入是我们的瓶颈;大部分时间都花在那里。我们花了很多时间试图调整表格和索引,但结果并不令人满意 假设我们有足够的内存,将数据插入内存而不是数据库的最佳实践是什么。目前,我们正在使用每秒更新和插入的数据表 我们的一位同事建议在提要处理程序和WCF用户请求处理

我们有一个应用程序,它获取实时数据并将其插入数据库。它每天在线4.5小时。我们在17个表中每秒插入数据。用户可以在任何时候查询任何表格,以获取最新的第二次数据和历史记录

使用C#控制台应用程序处理提要和插入

通过WCF服务处理用户请求

我们发现插入是我们的瓶颈;大部分时间都花在那里。我们花了很多时间试图调整表格和索引,但结果并不令人满意

假设我们有足够的内存,将数据插入内存而不是数据库的最佳实践是什么。目前,我们正在使用每秒更新和插入的数据表 我们的一位同事建议在提要处理程序和WCF用户请求处理程序之间使用另一个WCF服务,而不是数据库。WCF中间层应该是基于TCP的,它将数据保存在自己的内存中。有人可能会说,提要处理程序可能会处理用户请求,而不是在两个进程之间设置一个中间层,但我们希望将事情分开,这样,如果提要处理程序崩溃,我们仍然希望能够向用户提供当前记录

我们的时间有限,我们想在短时间内把所有的东西都记住。在2个过程中间有一个WCF是一件坏事吗?我知道请求会增加一些开销,但所有这三个进程(提要处理程序、内存数据库(WCF)、用户请求处理程序(WCF)都将在同一台机器上,带宽不会有太大问题


请协助!

您使用的是哪种数据库?MySQL有一个存储引擎内存,似乎适合这种情况。

您是否将DataTable与DataAdapter一起使用?如果是,我建议您完全删除它们。直接使用DBCommand插入记录。当用户请求报告时,使用data读取数据或者使用DataTable.Load(IDataReader)填充DataTable对象


在内存中编写数据的故事可能会在崩溃或电源故障时丢失数据。

我会考虑创建数据缓存(这样还可以减少数据库选择),并在缓存中的数据写入数据库后使其无效。这样,您可以批量调用以执行较大的插入,而不是许多较小的插入,但将数据保留在内存中,以便读取器可以读取数据。实际上,如果您知道数据何时过时,则可以避免完全读取数据库,并将其用作备份tore—这样,数据库性能只会影响缓存的大小

使缓存中的数据无效将取决于数据是否写入数据库或数据是否过时,后者总是最后一个,而不是第一个

缓存层不需要复杂,但是它应该是多线程的,以承载数据并将其保存在后台。该层将位于WCF服务、连接介质和WCF服务的后面,应该改进以包含控制台应用程序+批处理思想的逻辑。然后控制台应用程序可以连接ect到WCF并向其抛出结果


更新:唯一要说的是投资一个分析器,看看你是否在代码中引入了任何被掩盖的性能问题。另外,分析你的数据库。你提到你需要快速插入和选择-不幸的是,它们通常会相互取舍…

这是一个非常好的问题。我们正在使用SQL database.Microsoft SQL server 2008谢谢您的回答。数据不会过时,因为每个记录都是随时可选择的主题(用户可以指定他/她想要的第二个“记录”)。您的解决方案仍然建议插入数据库,尽管创建缓存的频率较低,但我想知道我们是否仍要从数据库中进行选择(如果数据不在缓存中,这是可能的,因为对于历史数据的选择是完全随机的)当Coincident插入一个巨大的表时,这不是会造成选择超时吗?我们不能将所有内容都叠加到内存中吗?这真的取决于-每秒插入4.5小时可能会产生大量数据?您的问题是插入性能-这可以通过其他方式解决。您可以做的是删除所有索引es因此为插入性能定制表,并在选择上产生成本,可能使用选择缓存在内存中保存更多。当然,在内存中是一种可行的方式,但内存也是易失性的-断电和它的全部消失。删除索引为我们提供了更好的性能,以及删除主键。这里的问题是我们希望快速插入和选择。在我们的股票市场领域,对表现的期望相当高。我建议采取一种折衷的方法——试试分布式缓存系统(memcache,Velocity)这样,您可以通过网络进行快速访问,但缓存中的一个项目会跨多台服务器进行复制,这在很大程度上消除了丢失实时数据的风险。仍将其保存到数据库中,但也将所有数据放在缓存中-唯一要衡量的指标是从缓存到数据库的时间以及数据量缓存中的数据在任何时候都未保存。我们创建了一个SQLTransaction连接,并使用SQLBulkCopy在DataTable中循环使用该连接进行插入。我们需要使用事务来逆转可能崩溃的影响