Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何加速这些ActiveRecord查询?_Ruby On Rails_Rails Activerecord - Fatal编程技术网

Ruby on rails 如何加速这些ActiveRecord查询?

Ruby on rails 如何加速这些ActiveRecord查询?,ruby-on-rails,rails-activerecord,Ruby On Rails,Rails Activerecord,我的数据库中有三个表:值、键和源。键和源都有许多值。sources有一个名为file\u date的datetime列。对于每个键,我必须选择源在特定日期范围(通常在两年内)之间的所有值。并非该范围内的所有日期都有来源,也并非所有来源都有值。我需要创建一个数组,其中包含该范围内的所有值 起初,我尝试一次简单地查询整个源数组,如下所示: Value.where(key: 1, source: sources_array) 但是,由于有几个值为零,因此它只返回在该日期具有值的记录 现在,我创建了一

我的数据库中有三个表:值、键和源。键和源都有许多值。sources有一个名为file\u date的datetime列。对于每个键,我必须选择源在特定日期范围(通常在两年内)之间的所有值。并非该范围内的所有日期都有来源,也并非所有来源都有值。我需要创建一个数组,其中包含该范围内的所有值

起初,我尝试一次简单地查询整个源数组,如下所示:

Value.where(key: 1, source: sources_array)
但是,由于有几个值为零,因此它只返回在该日期具有值的记录

现在,我创建了一个数组,其中包含该日期范围内的所有源。没有来源的日子只有零。然后,对于每个键,我遍历sources数组,返回与foo和source匹配的值。这显然是不理想的,页面加载大约需要7秒钟

这是代码:

sources.map do |source|
  Value.where(source: source, key: key)
end

有什么想法吗

您的
.map
的一个大问题是,它运行多个查询,而不是一个包含所有所需结果的查询。对于每个额外的查询,您都会增加将请求发送到数据库和接收响应的开销。您需要做的是以一种返回您可能要查找的所有结果的方式生成查询,然后处理任何分组或排序应用程序端

您可以尝试在单个事务中包装查询:

ActiveRecord::Base.transaction do
  sources.map do |source|
    Value.where(source: source, key: key)
  end
end

我需要疯狂地重构它,但我有一些东西把它缩短到了3秒:

  source_ids = sources.map do |source|
    if source
      source.id
    else
      nil
    end
  end

  values = Value.where(source: sources, key: key)
  value_sources = values.pluck(:source_id)
  value_decimals = values.pluck(:value_decimal)

  source_ids.map do |id|
    index = value_sources.index(id)

    if index
      value_decimals[index]
    else
      nil
    end
  end

如果只需要检索数据,并且获取数组就足够了,那么还可以生成一个SQL查询

output = []

sources.each do |source|   
  output << "select * from values where (source like #{source} and key like #{key})"   
end

result = ActiveRecord::Base.connection.execute(output.join(" union ")).to_a
output=[]
sources.each do|source|

我已经试过了。我找不到任何东西,如果ActiveRecord找不到任何东西,它将返回nil。如果它找不到任何东西,它应该返回一个与空数组等效的对象。您可以调用
.to_a
获取数组,也可以调用
.empty?
在没有结果时返回true有结果,但源数组的某些值为零(因为那天没有源)。ActiveRecord只是忽略数组中的nil值。另外,那天还有一些源没有该键的值。我刚刚尝试过,但它仍然在7秒时计时。我得到了以下错误:
ActiveRecord::StatementInvalid:PG::SyntaxError:error:内存在“源”或“源”附近耗尽
您可以尝试将“联合”更改为“联合所有”,关于这个SE问题:这似乎是PostgreSQL中组合多个select查询的常用方法。