【问题标题】:How can I get rid of n+1 query attributed to rails association?如何摆脱归因于 rails 关联的 n+1 查询?
【发布时间】:2015-10-24 22:27:19
【问题描述】:

我的代码中有一行如下所示...

injury.player_extract.player

我收到来自名为 bullet 的 gem 的通知,提示检测到 n+1 查询。现在有一个从受伤到球员提取的关联,然后是球员提取到球员——我将在下面概述。我尝试添加-> { includes: player},因为这是子弹推荐的内容,但我仍然收到错误消息。谁能解释为什么我仍然会收到它?

协会

injury.rb

belongs_to :player_extract, -> { includes :player },  class_name: 'PlayerExtract', foreign_key: 'Playerid', primary_key: 'Playerid'

player_extract.rb

belongs_to :player, foreign_key: 'Playerid', primary_key: 'leagueid'

player.rb

has_one :player_extract, class_name: 'PlayerExtract', foreign_key: 'Playerid', primary_key: 'leagueid'

【问题讨论】:

  • 你到底为什么要使用列名Playerid?除非您必须与其他旧版应用程序共享数据库,否则您应该将其重命名为 player_id
  • 您在旧版应用程序中做对了,我无法控制名称 - 尽管我只是...我可以使用 alias_attribute 来获得 player_id 的功能吗?如果它比是/否更深入,也许我应该有一个单独的问题
  • PlayerExtract模型的作用是什么?
  • PlayerExtract 与 Player 类似,只是它们位于两个不同的数据库中,属性略有不同,但有很多共同点。所以我只是访问播放器模型以访问其上的 id 字段——这并不理想,但正如我所说,我无法控制数据。
  • 您能否添加您的 schema.rb 或相关部分的摘录?您可能想声明一个关于伤害的has_one :player, through: :player_extract 关系 - 但我想测试一下答案,因为它是一个非常规的案例。

标签: ruby-on-rails ruby activerecord associations eager-loading


【解决方案1】:

您可能应该对所有数据使用预先加载来解决问题。

从简短的检查来看,您似乎在 injury.rb 上使用了 includes 指令,但在 player_extract.rb 上没有使用 - 因此,每当使用 PlayerExtract 访问实际数据时,Player 就会延迟加载.

看看这些链接:

我可能会考虑使用带有 joins (here) 或 includes 指令的专用范围...我不确定将指令放在关系声明中 (has_one 等) 是最好的办法。

【讨论】:

    猜你喜欢
    • 2013-07-22
    • 1970-01-01
    • 2015-02-06
    • 2017-07-20
    • 2013-06-14
    • 2020-06-25
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多