数据库插入性能

时间:2010-03-06 20:24:41

标签: c# mysql sql-server sqlite

我们计划实施一个系统,将高频率的市场价格记录到数据库中进行进一步分析。为了简单地了解我们可以在不同的数据库解决方案上获得什么样的存储性能,我创建了一个用于插入基本行标记信息的小应用程序。在几个不同的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的循环,其中来自NASDAQ的真实历史数据已编译成已导入内存的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个价格。

8 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:3)

  

此测试的目的很简单   得到一些指示   那种“原始表现”可以   期望系统在底部。   实际实施解决方案时   我们当然会做缓冲,批量   插入等。

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

但无论如何,如果你想要一个高度可扩展的写优化数据库,请查看Apache Incubation的CassandraThe rumor mill says Twitter will adopt it soon

答案 2 :(得分:2)

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

答案 3 :(得分:1)

如果您想要仅插入操作,可以使用Archive engineINSERT DELAYED从mysql中获取更多信息。

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

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

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

答案 7 :(得分:0)

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

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