【发布时间】:2013-04-02 16:33:29
【问题描述】:
我有一个场景,我在查询链中的某处有 SQL 连接,然后在更进一步的点我需要附加一个需要相同连接的条件,但我现在不知道该连接是否已经存在范围内。例如:
@foo = Foo.joins("INNER JOIN foos_bars ON foos_bars.foo_id = foos.id")
....
@foo.joins(:bars).where(bars: { id: 1 })
这将产生一个关于重复表/别名的 SQL 错误。
我在第一个实例中手动编写 SQL 连接的原因是为了提高效率,因为经典的 Rails AREL 连接会产生两个 INNER JOINS,而我只需要一个。
有没有推荐的解决方法?例如,某种检查当前范围内连接的方法。
对评论的回应:
使用has_and_belongs_to_many 关系Rails 产生两个INNER JOINS,如下所示:
SELECT "journals".* FROM "journals"
INNER JOIN "categories_journals"
ON "categories_journals"."journal_id" = "journals"."id"
INNER JOIN "categories"
ON "categories"."id" = "categories_journals"."category_id"
WHERE "categories"."id" = 1
而我相信我可以这样做:
SELECT "journals".* FROM "journals"
INNER JOIN "categories_journals"
ON "categories_journals"."journal_id" = "journals"."id"
WHERE "categories_journals"."category_id" = 1
如果我错了,请纠正我。
【问题讨论】:
-
你做了什么样的分析来证明你更“有效”的连接方式实际上更好?实际上,是什么让您认为您只需要一个加入?即使您一遍又一遍地尝试连接同一个表,AREL 也不会构建不必要的连接。
-
我更新了我的问题,因为@messick 的评论太长了。
-
我建议让 AREL 做这件事。您的解决方案正在破坏 ORM 的主要优势之一,即“自动”拥有映射到数据库表的对象。如果加入 Categories 表对性能真的有那么大的影响,我会回去考虑一下 Rails 是否真的是你想要使用的东西。
-
我认为仅仅因为我选择在 SQL 中编写某些方面是出于性能原因而说我正在击败 ORM 的对象或使用 Rails 本身,这有点愚蠢。很多事情你在 AREL 中根本做不到,必须使用 SQL。我有一个包含大约 6 个多对多模型连接的查询,如果我可以将 SQL 连接的数量减少一半,为什么不呢?使用 Rails 并不是为了性能。
标签: ruby-on-rails