【问题标题】:How to merge two double joins in ActiveQuery如何在 ActiveQuery 中合并两个双连接
【发布时间】:2021-04-26 22:04:06
【问题描述】:

我有两个双重连接(我相信这就是他们会考虑的),单独执行它们似乎非常慢。我知道关于单个查询是否比多个查询更快以及反之亦然存在争议,但我愿意尝试任何事情。

这是我现有的陈述:

line_stops = OpsHeader.joins(
        ops_stop_rec: :driver_header
      )
    .select(
        :pbbname,
        :pb_net_rev,
        :ops_driver1,
        :pb_id,
        :ops_stop_id,
        :dh_first_name,
        :dh_last_name,
        :ops_delivered_time
      )
      .where(
        :ops_stop_rec => {
            ops_arrive_time: params[:startDate] .. params[:endDate]
        })


    line_items = OpsHeader.joins(
        ops_stop_rec: :ops_line_items
      ).select(
        :pbbname,
        :opl_amount,
        :pb_id,
        :ops_type,
        :ops_stop_id,
        :ops_order_id,
        :ops_driver1,
        :ops_delivered_time
      )
      .where(
        :ops_stop_rec => {
            ops_arrive_time: params[:startDate] .. params[:endDate]
        }
      )

仅供参考,我是从旧的 Firebird 数据库中提取这些,并且服务器硬件也不一定很快,所以可能比我想象的要多。此外,在将数据提供给客户之前,我必须在此之上进行数据操作。

无论如何,这是我的联想:

class OpsHeader < ApplicationRecord
  belongs_to :pb_bill
  belongs_to :pb_master

  has_many :ops_stop_rec, foreign_key: 'ops_order_id'

  self.table_name = 'OPS_HEADER'
  self.primary_key = 'pb_id'
end
class OpsStopRec < ApplicationRecord
  #belongs_to :ops_order
  #belongs_to :ops_im_equip
  belongs_to :ops_header, foreign_key: 'pb_id'
  belongs_to :driver_header, foreign_key: 'ops_driver1'

  has_many :ops_line_items, foreign_key: 'opl_stop_id'

  self.table_name = 'OPS_STOP_REC'
  self.primary_key = 'ops_stop_id'


end
class OpsLineItem < ApplicationRecord
  #belongs_to :opl_order
  #belongs_to :opl_stop

  belongs_to :ops_stop_rec, foreign_key: 'ops_stop_id'

  self.table_name = 'OPS_LINE_ITEMS'
  self.primary_key = 'opl_stop_id'
end
class DriverHeader < ApplicationRecord
  #belongs_to :dh_paythru
  has_many :ops_stop_rec, foreign_key: 'ops_driver1'
  
  self.table_name = 'DRIVER_HEADER'
  self.primary_key = 'dh_id'
end

【问题讨论】:

  • “旧火鸟数据库” - 几岁了?什么是数据库版本?您可以将其克隆到开发环境并将服务器升级到 firebird 2.5 吗? “服务器硬件不一定很快” Groton/Interbase/Firebird 是在 1970 年代构想出来的,当时 RAM 非常昂贵且非常稀缺。您可以在 ib-aid.com 上考虑优化的、RAM 宽松的 Firebird 配置和有关手动优化的文章
  • 你能在你的服务器上运行这个查询吗? - dbfiddle.uk/?rdbms=firebird_3.0 - 如果我的记忆还好,它会从 FB 2.0 开始工作,但在 FB 1.x 上会失败

标签: ruby-on-rails ruby activerecord firebird


【解决方案1】:

您要查找的是union operator。有a gem可以帮你搞定。

或者尝试使用两个左外连接并添加一个 OR 条件。

【讨论】:

  • 虽然这些对合并有帮助,但您认为它们对业绩有帮助吗?
  • 不一定,取决于您拥有的数据。带有 or 条件的左外连接应该比联合快,因为联合基本上是在数据库内部执行两个查询。这仍然比执行两个单独的查询要好,因为您节省了一次到数据库的往返。但这可能只是一个边际改进,因为它只是一次往返。顺便说一句,最好先执行 UNION ALL,然后对其应用 DISTINCT,而不是仅仅执行 UNION。所以我会先从左外连接开始,因为它似乎是最有前途的。
  • @AttemptedMastery 如果您想优化性能,我认为您必须从 ORM 和 AR 的高抽象层跳到较低级别的 SQL 等。您可能必须优化数据库结构和在普通 SQL 中找到最佳查询,然后您将爬回 ORM/AR 抽象并尝试强制它们生成类似于您在 SQL IDE 中手工制作的查询。特别是,如果没有关于 Firebird 采用的数据库方案、数据和执行路径的真实信息,您的问题 do you think they'll help performance 将无法回答
猜你喜欢
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
  • 2019-03-06
相关资源
最近更新 更多