使用Bullet和RSpec gems减少n + 1个查询

时间:2014-10-08 00:14:39

标签: ruby-on-rails ruby rspec rails-bullet

使用Bullet Gem和RSpec的有效方法是什么?现在我觉得如果我将它与我当前的单元测试框架一起使用,我会得到很多通知或测试失败,因为测试本身内的n + 1个查询与我的生产应用程序中发生的事情无关,例如检查价值或联想。因此,修复n + 1故障不需要在我的控制器或模型上设置任何内容,而是需要在我的测试设置中设置一些内容以避免抛出该特定错误,并且我发现我的应用程序没有真正的性能改进。

2 个答案:

答案 0 :(得分:8)

最有效的方法根本不是。在测试中减少n + 1个查询可能有一些合理的优点,最明显的是加快总体执行时间。但是,您很可能testing too much或收益不如what is possible。我还经常发现编写额外的代码以帮助支持测试而不是为应用程序的整体价值做出贡献是没有吸引力的。

请允许我建议您替代使用您的时间。只有单元测试才能达到您舒适程度的绝对最低水平。我个人喜欢专注于涉及验证相关问题和金钱或其他数学的复杂方法,您可能有不同的优先级。划清界限将释放大量时间来编写测试套件中最无用且最脆弱的部分,这将占用您的大部分维护预算。

现在,你要做的就是你所有的额外时间?别担心,我们会为您找到一些东西......您可以从编写一些验收测试开始,特别是对于那些使用您刚刚放弃了大量单元测试的对象的区域。现在,您的n + 1警告实际上来自用户点击页面时的相同位置。现在,您可以继续删除所有n + 1个查询。

但是等等!也不要这样做。相反,花费更少的时间setting up your relationships to use the touch option。然后,当子对象更新时,父级也将更新。这可能与n + 1查询有什么关系,你可能会想知道。我们似乎只是添加了查询...

Russian doll caching进来的地方。添加它并正确测试它将消耗释放的单元测试和n + 1消除时间(然后是一些,如果你的话不小心)。好消息是,它更像是真实的世界",对于模型中的微不足道或无关紧要的实现变化以及诸如此类的东西更具弹性,并且对应用程序的巨大性能提升远远超出消除每个n + 1的应用程序通过热切地加载前面的所有内容可能提供了查询。您将希望尽可能多地移动到嵌套缓存中并尽可能懒散地加载所有内容,以充分利用此方法。

万岁n + 1!

答案 1 :(得分:0)

Bullet gem将在屏幕上显示N + 1个查询。通过使用渴望的加载方法,我们可以杀死N + 1个查询。它将提高应用程序的性能。此N + 1查询问题主要发生在has_many关联的情况下。提高应用程序性能的最佳方法是片段缓存,它确实可以减少页面的加载时间并提高应用程序的性能。

<% @products.each do |product| %>
  <% cache product do %>
    <%= render product %>
  <% end %>
<% end %>