【问题标题】:Database insert performance数据库插入性能
【发布时间】:2011-01-24 12:57:13
【问题描述】:

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

插入的数据很简单,如下:

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]

微软 SQL 服务器:

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

MySQL 服务器:

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

MongoDB 服务器:

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

此测试的目的只是为了了解底层系统可以预期的“原始性能”类型。在实际实施解决方案时,我们当然会进行缓冲、批量插入等。

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

有人对其他适合的数据库有什么建议吗?今晚晚些时候我也会尝试使用 HDF5 和 MonetDB。它需要具有多客户端访问权限。

感谢您的任何建议!

更新:

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

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

当前的测试是一个简单的循环,将行插入到数据库中,将来自纳斯达克的真实历史数据编译到已导入内存的 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 个价格。

【问题讨论】:

  • 您也应该使用缓冲和批量插入进行测试。还要确保使用与真实系统相同的索引和约束,并使用合理填充的 Db 进行测试。
  • 还请记住,硬件在这里非常重要,例如一些高端 SSD 驱动器将提供更好的性能,所以看看你在哪里花钱,看看它有多重要。跨度>
  • 您是在同一台机器上测试它们吗?你用的是 sql server express edition 吗?
  • 当您披露您使用的存储引擎(innoDB、MyIsam 等)时,讨论 mySQL 基准测试更有意义。此外,您没有透露您需要使用哪种密钥。您的行有唯一标识符吗?新行有时会替换旧行吗?你将如何检索数据?如果答案是“始终按顺序”,那么您最终会得到一个非常不同的数据库设置,而不是您需要“按市场代码和时间戳范围”检索。
  • TiTaN,它是 SQL Server 2008 Enterprise x64。

标签: c# mysql sql-server sqlite


【解决方案1】:

我只能对sql-server真正发表评论,但是有一些事情可以尝试:

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

两者都应该对单行插入进行显着改进(后者最快)

【讨论】:

  • +1 - 我最近在博客上写了一个使用 SqlBulkCopy 与使用 SqlDataAdapter 批量更新的性能比较:adathedev.co.uk/2010/02/… 结果是 0.8229 秒,在我的家用 PC 上插入 100,000 条记录。
  • 确实很有趣。但是SqlBulkCopy在做insert的时候有需要独占访问表的问题,不是吗?
  • @Erik - 这取决于您为锁定模式选择的内容。 "table" 是最快但排他的。还有更多细粒度的选项。
  • 虽然这个问题很老,但性能问题一直很受关注,因为我在这里看不到它,我想我应该发布我最近使用 SQL Server 的经验。我尝试了单插入、多插入和 sqlbulkCopy。每个都比另一个快,没有一个速度足以满足我导入 6-8 百万条记录的要求。其中最快的等待时间太长。以编程方式调用存储过程来批量导入 3 个预解析的制表符分隔文件(解析/写入所有 3 个日志的时间小于 1 分钟),3 个本地化文件中的整个记录​​集将在约 4 分钟内导入。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

      如果您的数据可以表示为键/值对(就像在 PERL 哈希或类似数据结构中一样),BerkeleyDB 可能值得一看。它快速、多客户端和事务安全,即使它不是最新的 wizbang 东西。

      【讨论】:

        【解决方案5】:

        如果您想要只进行插入操作,您可以使用Archive engineINSERT DELAYED 来充分利用mysql。

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

        【讨论】:

          【解决方案6】:

          您是使用多个连接数据库服务器并同时插入数据的应用程序实例进行测试,还是仅使用一个应用程序进行测试?

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

          PS:如果我在这里陈述显而易见的事情,请原谅我。

          【讨论】:

            【解决方案7】:

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

            【讨论】:

            • 没错,如果查询稍后完成,没有人能比简单地追加到文本文件的性能更好。
            【解决方案8】:

            我也会考虑检查 MySQL 5.5 候选版本。 Oracle 人员在此版本中进行了重大改进,特别是针对 Windows 版本。读/写操作的性能提升高达 1,500%,只读操作的性能提升高达 500%。您可以参考此链接了解更多信息:

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

            【讨论】:

              猜你喜欢
              • 2022-01-04
              • 1970-01-01
              • 2016-07-08
              • 2016-12-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-07-06
              • 2011-04-01
              相关资源
              最近更新 更多