13

在注意到我们的数据库已成为我们实时生产系统的主要瓶颈后,我决定构建一个简单的基准来查明问题的根源。

基准:我计算了将 InnoDB 表中的同一行增加 3000 次所需的时间,其中该行由其主键索引,并且正在更新的列不属于任何索引。我使用远程机器上运行的 20 个并发客户端执行这 3000 次更新,每个客户端都有自己独立的数据库连接。

我有兴趣了解为什么我进行基准测试的不同存储引擎 InnoDB、MyISAM 和 MEMORY 具有它们所做的配置文件。我也希望了解为什么 InnoDB 相比之下表现如此糟糕。

InnoDB(20 个并发客户端):每次更新耗时 0.175s。所有更新均在 6.68 秒后完成。

MyISAM(20 个并发客户端):每次更新需要 0.003 秒。所有更新都在 0.85 秒后完成。

内存(20 个并发客户端):每次更新耗时 0.0019 秒。所有更新都在 0.80 秒后完成。

考虑到并发性可能会导致这种行为,我还对单个客户端执行 100 次顺序更新进行了基准测试。

InnoDB:每次更新需要 0.0026 秒。

MyISAM:每次更新需要 0.0006 秒。

内存:每次更新需要 0.0005 秒。

实际机器是一个 Amazon RDS 实例 ( http://aws.amazon.com/rds/ ),大部分是默认配置。

我猜答案将如下所示:每次更新后的 InnoDB fsyncs(因为每次更新都是符合 ACID 的事务),而 MyISAM 不支持,因为它甚至不支持事务。MyISAM 可能在内存中执行所有更新,并定期刷新到磁盘,这就是它的速度接近 MEMORY 存储引擎的方式。如果是这样,有没有办法使用 InnoDB 来支持它的事务,但也许可以放松一些约束(通过配置),以便以一些持久性为代价更快地完成写入?

另外,随着客户数量的增加,关于如何提高 InnoDB 性能的任何建议?它的扩展性显然比其他存储引擎差。

更新

我找到了https://blogs.oracle.com/MySQL/entry/comparing_innodb_to_myisam_performance,这正是我想要的。设置 innodb-flush-log-at-trx-commit=2 允许我们在发生电源故障或服务器崩溃的情况下放松 ACID 约束(每秒刷新一次磁盘)。这为我们提供了与 MyISAM 类似的行为,但我们仍然可以从 InnoDB 中可用的事务功能中受益。

运行相同的基准测试,我们看到写入性能提高了 10 倍。

InnoDB(20 个并发客户端):每次更新耗时 0.017 秒。所有更新都在 0.98 秒后完成。

还有其他建议吗?

4

2 回答 2

6

我找到了https://blogs.oracle.com/MySQL/entry/comparing_innodb_to_myisam_performance,这正是我想要的。设置 innodb-flush-log-at-trx-commit=2 允许我们在发生电源故障或服务器崩溃的情况下放松 ACID 约束(每秒刷新一次磁盘)。这为我们提供了与 MyISAM 类似的行为,但我们仍然可以从 InnoDB 中可用的事务功能中受益。

运行相同的基准测试,我们看到写入性能提高了 10 倍。

InnoDB(20 个并发客户端):每次更新耗时 0.017 秒。所有更新都在 0.98 秒后完成。

于 2012-05-07T21:21:05.170 回答
5

我们在我们的应用程序中进行了一些类似的测试,我们注意到如果没有显式打开事务,则每条 SQL 指令都会在事务中处理,这需要更多时间来执行。如果您的业务逻辑允许,您可以将多个 SQL 命令放在一个事务块中,从而减少总体 ACID 开销。在我们的案例中,我们通过这种方法获得了很大的性能提升。

于 2012-05-05T02:01:36.607 回答