禁用ActiveRecord延迟加载进行调试?

时间:2018-04-12 16:49:29

标签: ruby-on-rails activerecord

我正在成熟的代码库上调试一个非常复杂的查询。

我们的性能监控工具已在代码库的复杂部分中识别出N + 1,我们假设它们没有延迟加载。

我想在调试某些代码段时暂时禁用(或崩溃)延迟加载。

# In my test suite or while debugging:

PseudoCode.disable_lazy_loading!
SuspectedNPlusOne.run(params) # Crash if lazy loading occurs
PseudoCode.enable_lazy_loading!

如何为了调试而禁用延迟加载或暂时崩溃数据库读取?

1 个答案:

答案 0 :(得分:1)

ActiveRecord的查询API围绕延迟加载的概念。当我尝试清理N + 1个查询时,我发现自己一直在与AR的设计工作方式作斗争,这使人们很容易说“ Meh,计算机速度足够快”。

这是我决定将Elixir / Phoenix用于所有未来开发工作的几个可用性原因之一; Ecto ORM使得实际上不可能延迟加载数据;您要么在查询评估时加载关联,要么没有关联的数据,则需要稍后对其进行显式查询。

一个非常不完整的建议:安装Bullet gem,并在发现延迟加载时使用其Bullet.raise = true设置使应用程序崩溃。使用Bullet进行故障排除很麻烦,因为它与ActiveRecord的自然行为作斗争,因此只能告诉您延迟触发N + 1查询的位置,而不告诉您查询最初在代码中的位置(以及您可能需要添加{{1 }})。但是至少有了这个地方,您就可以获得所需的部分信息:

  • 此代码是否执行明显的N + 1查询?
  • 在代码中的哪里触发了N + 1查询?
  • 罪魁祸首是什么类别和协会名称?