我正在尝试优化我的数据库调用以进行长期rake任务,因此我一直在分析每个查询。
我注意到Rails经常用BEGIN
和COMMIT
包装我的插入和更新。我没有在任何地方使用.transaction
所以我很困惑为什么会发生这种情况。我已禁用我的after_save
和after_commit
日志记录,但这似乎没有效果。
有任何想法吗?亚马逊网络服务测量每一个MySQL I / O,所以我想摆脱这些BEGIN
和COMMIT
语句。
谢谢!
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
如果你将这些调用包装在explicit transaction中,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
你实际上并不想摆脱它们。 Active Record在幕后扮演了很多魔力,因此在保存复杂模型/关系时,如果出现问题,事务包装器对于撤消数据库更改非常有用。
注意,这与你使用.transaction
无关。 Active Record会在数据库事务中自动包含.save
和.update_attribute
等常用操作。
BEGIN和COMMIT并不是一个过载,而是我必须说的救星。如果出现问题,它们可以帮助您回滚事务。虽然你没有使用.transaction
,但它们默认是作为Rails的背景魔法实现的。
如果您真的想在AWS服务上节省成本,请尝试删除不会妨碍您的应用程序安全性和健壮性的内容。