数据库插入性能

我们计划实施一个系统,将高频率的市场价格记录到数据库中进行进一步分析。 为了简单地了解我们可以在不同的数据库解决方案上获得什么样的存储性能,我创建了一个用于插入基本行标记信息的小应用程序。 在几个不同的DB上运行相同的代码时,我们得到了一些有趣的结果。

插入的数据非常简单如下:

CREATE TABLE [dbo].[price]( [product_code] [char](15) NULL, [market_code] [char](10) NULL, [currency] [nchar](6) NULL, [timestamp] [datetime] NULL, [value] [float] NULL, [price_type] [char](4) NULL ) ON [PRIMARY] 

Microsoft SQL Server:

总测试时间:32秒。 每秒3,099个价格。

MySQL服务器:

总测试时间:18秒。 每秒5,349个价格。

MongoDB服务器:

总测试时间:3秒。 每秒25,555个价格。

此测试的目的仅仅是为了获得底部系统可以预期的“原始性能”的一些指示。 当实际实施解决方案时,我们当然会做缓冲,批量插入等。

我们只关心插入的速度,因为查询是在以后“离线”完成的。

有没有人对其他适合的数据库有任何建议? 今晚我也将尝试使用HDF5和MonetDB。 它需要具有多客户端访问权限。

谢谢你的任何建议!

更新 :

抱歉,我在定位之前对我的问题进行了重大编辑,似乎我遗漏了服务器版本和硬件的一些细节。 所有测试都在8核服务器上运行,其中12GB RAM运行Windows 2008 x64。

Microsoft SQL Server 2008 Enterprise x64。 MySQL 5.1.44作为InnoDB表运行。 MongoDB 1.2.4 x64

当前测试是一个简单的行插入DB的循环,其中纳斯达克的真实历史数据已编译成已导入内存的CSV文件。 代码在C#NET4 x64中。

MS SQL和MySQL服务器被“调整”到完美设置,而MongoDB只是设置了默认设置。 SQL表的设置没有索引,因为在转移到主分析系统之前,DB的目的很简单,因为它是一个临时基础。

许多建议使用批量插入,但这是一种难以实现的方式,因为我们有几个客户端将单个刻度线独立于实时流推送到数据库中。 为了允许这样的方法,我们必须将数据库前面的层扩展到我们现在有机会测试的范围之外。 但是我想象最终架构必须要做的事情,因为我们从除MongoDB之外的所有东西获得的数字不足以处理所需的输入数量。

更新2:SSD驱动器确实非常适用于此,我们自己也在使用它。 然而,最终的产品将安装在几个不同的客户,这些客户都提供自己的铁..而从IT部门获取SSD的服务器仍然很难…… 🙁

更新3:

我尝试了BulkCopy方法。 与其他循环相同的循环的性能,但首先进入DataTable然后BulkInsert进入SQL Server导致以下结果:

Microsoft SQL Server(批量):

总测试时间:2秒。 每秒39401个价格。

我只能对sql-server发表评论,但有些事情要尝试:

  • 命令批处理(即在单击中对数据库执行多次INSERT
  • 批量插入(通过SqlBulkCopy

要么应该对单行插入进行重大改进(后者最快)

此测试的目的仅仅是为了获得底部系统可以预期的“原始性能”的一些指示。 当实际实施解决方案时,我们当然会做缓冲,批量插入等。

您至少可以分享测试的详细信息。 省略如你所尝试的MySQL引擎这样的重要信息是不可原谅的。 基于缓冲池的数据库(如SQL Server或InnoDB)上的非批量插入的“原始性能”是无意义的,就像测量法拉利的第一档“原始性能”然后发布“它只能达到50英里每小时”。

但无论如何,如果你想要一个高度可扩展的写优化数据库,请查看Apache Incubation的Cassandra 。 谣言工厂称Twitter将很快采用它 。

这些与简单地记录到文件系统中的平面文件相比如何? 如果稍后进行查询,我不确定为什么此时将数据带入关系数据库。 在此录制阶段是否需要交易或多次访问数据库?

如果你想要只插入操作,你可以通过使用Archive引擎和INSERT DELAYED来获得更多的mysql。

否则,请尝试任何本地存储KV引擎:BDB,QDBM,Tokyo Cabinet等。

有许多方法可以优化性能,不同的数据库也可以处理非常不同的数据。 例如,SQL Server正在保护您的数据,它必须确保数据有效且在磁盘上才能让您知道插入已经成功。 MySQL和MongoDB都是这样做的,所以它们可以更快。 你在找什么? 一个RDBMS或一些存储器,你可以负担得起它丢失一些数据?

如果您的数据可以表示为键/值对(如在PERL哈希或类似的数据结构中),那么BerkeleyDB可能值得一看。 即使它不是最新的wizbang,它也是快速,多客户和交易安全的。

您是否测试了连接数据库服务器并同时插入数据或仅插入一个应用程序的多个应用程序实例?

我认为你应该测试多个实例,尤其是批量插入,看看哪些配置适合你。 不同的事务隔离模式会极大地影响并发访问(尤其是写访问)的性能。 以SQL Server为例,我发现比ReadCommitted 更低的隔离模式应该用于高度并发的环境,否则你会发现很多超时的情况。 这当然应当在不重视脏读的风险时使用(根据您的描述判断适合您的情况)。

PS:如果我在这里陈述明显的话,请原谅我。

我也会考虑检查MySQL 5.5发布候选版本。 Oracle家伙在这个版本上做了重大改进,特别是对于Windows版本。 读/写操作的性能提boost达1,500%,而只读高达高达500%的性能提升。 您可以参考此链接获取更多信息:

http://www.mysql.com/news-and-events/generate-article.php?id=2010_04