3

我正在尝试优化我的数据库调用以完成一个长耙任务,所以我一直在分析每一个查询。

我注意到 Rails 经常用BEGIN和包装我的插入和更新COMMIT。我没有.transaction在任何地方使用,所以我很困惑为什么会这样。我已禁用我的after_saveafter_commit日志记录,但这似乎没有效果。

有任何想法吗?Amazon Web Services 测量每一个 MySQL I/O,所以我想摆脱这些BEGINCOMMIT语句。

谢谢!

4

3 回答 3

5

Rails 将每个写入封装在一个事务中。例子:

Foo.create
Foo.create
Foo.create

日志:

 (0.1ms)  BEGIN
SQL (6.9ms)  INSERT INTO `foos` VALUES ()
 (3.3ms)  COMMIT

 (0.2ms)  BEGIN
SQL (8.0ms)  INSERT INTO `foos` VALUES ()
 (0.4ms)  COMMIT

 (0.2ms)  BEGIN
SQL (7.3ms)  INSERT INTO `foos` VALUES ()
 (1.3ms)  COMMIT

如果您将这些调用包装在显式事务中,Rails 将使用该事务而不是创建新事务:

Foo.transaction do
  Foo.create
  Foo.create
  Foo.create
end

日志:

 (0.2ms)  BEGIN
SQL (0.3ms)  INSERT INTO `foos` VALUES ()
SQL (0.2ms)  INSERT INTO `foos` VALUES ()
SQL (0.2ms)  INSERT INTO `foos` VALUES ()
 (6.7ms)  COMMIT
于 2013-10-20T07:04:06.127 回答
3

您实际上并不想摆脱它们。Active Record 在幕后做了很多神奇的事情,因此在保存复杂的模型/关系时,事务包装器对于在出现问题时撤消数据库更改非常有用。

请注意,这与您使用.transaction. Active Record 会自动将常见的操作包装起来,比如.save数据库.update_attribute事务。

于 2013-10-12T23:52:23.533 回答
2

BEGIN 和 COMMIT 不是超载,而是我必须说的救星。它们可以帮助您在出现问题时回滚事务。尽管您没有使用.transaction它们,但它们默认实现为 Rails 的背景魔法。

如果您真的想在 AWS 服务上省钱,请尝试删除不会妨碍您的应用程序安全性或稳健性的 sumthing。

于 2013-10-13T06:30:02.563 回答