【问题标题】:How to attach raw SQL to an existing Rails ActiveRecord chain?如何将原始 SQL 附加到现有的 Rails ActiveRecord 链?
【发布时间】:2023-03-27 03:00:01
【问题描述】:

我有一个规则构建器,它最终通过链接多个 where 调用来构建 ActiveRecord 查询,如下所示:

Track.where("tracks.popularity < ?", 1).where("(audio_features ->> 'valence')::numeric between ? and ?", 2, 5)

然后,如果有人想对结果进行随机排序,它会附加order("random()")

但是,考虑到表的大小,random() 的排序效率极低,因此我需要使用 Postgres TABLESAMPLE-ing。

在原始 SQL 查询中,如下所示:

SELECT * FROM "tracks" TABLESAMPLE SYSTEM(0.1) LIMIT 250;

有没有办法将TABLESAMPLE SYSTEM(0.1) 添加到现有的 ActiveRecord 调用链中?将其放在 where()order() 中不起作用,因为它不是 WHERE 或 ORDER BY 函数。

【问题讨论】:

  • 我稍微研究了一下,向Arel::Nodes::SelectManager 添加全新的结构似乎很难做到。特别是在这种情况下,因为 TABLESAMPLE 必须位于查询的末尾。您可能想尝试在 Rails 核心开发人员邮件列表上提问,因为他们可能对 Arel 的深奥内部运作有一些见解。

标签: ruby-on-rails activerecord


【解决方案1】:
irb(main):004:0> Track.from('"tracks" TABLESAMPLE SYSTEM(0.1)')
  Track Load (0.7ms)  SELECT "tracks".* FROM "tracks" TABLESAMPLE SYSTEM(0.1) LIMIT $1  [["LIMIT", 11]]

【讨论】:

  • 要附加到现有链上,这将不起作用,尽管可能类似于 Trak.from("#{existing_chain.to_sql} TABLESAMPLE SYSTEM(0.1)") 但这会破坏额外的链接,因此它将非常依赖于顺序
  • 在某些情况下它会在其他列上进行 JOIN,因此如果在 JOIN 之前插入 TABLESAMPLE,那么它基本上会杀死 JOIN。
  • @Shpigford 是否会涉及额外的订购或只是表格样品没有订购
  • @engineersmnky 没有额外订购。只是 TABLESAMPLE。
  • @engineersmnky arel 是否可能是错误的方法名称?它吐出SELECT "tracks".* FROM #&lt;Arel::Nodes::TableAlias:0x00007fc02254ec48&gt; TABLESAMPLE SYSTEM(0.1)(反过来,抛出一个错误)。
猜你喜欢
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 2011-12-11
  • 2020-05-27
  • 1970-01-01
  • 2018-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多