这实际上不是一个查询,它是一大堆其他的东西。您正在解析文件并根据该文件的内容写入数据库。此外,如果您所做的只是为数据库播种,则根本没有理由让应用程序或浏览器参与其中。通过rake任务或rails控制台可以更好地完成此任务。您可以通过将操作分解为单独的部分来避免数据库超时,例如
无论如何,你应该完全从应用程序中取出数据库的这个种子。
你可以用一个 ActiveRecord的进口 gem - 主要思想是通过一个查询加载许多记录。
您必须将列名指定为数组:
column_names = [:name, :quantity, :unit_type, :food_id]
接下来,您必须以相同的顺序从csv加载数据:
row_values = [ ["Sirloin Steak with Blue Cheese Compound Butter", 1, "Butter", 2], ["Something else", 2, "else", 32], ... ]
和导入:
DbIngredient.import(column_names, row_values)
你试图在一个http请求/响应周期内做太多事情。对于CSV中的每一行,您都在使用sql INSERT (与 dbUser.recipes.create ),一个 UPDATE (与 dbRecipe.save ), 以及ASA SELECT (与 Food.find_by_name(food) )。
INSERT
dbUser.recipes.create
UPDATE
dbRecipe.save
SELECT
Food.find_by_name(food)
即使您进行了一些优化,您确定CSV在应用程序的生命周期内只有大约300行吗?即使答案是肯定的,一般来说,最好尽快响应用户操作,而不是让他们看着他们的浏览器等待响应。
所以,我建议你重新考虑你的方法。如果单个操作必须执行许多sql命令,请考虑使任务以异步方式运行的方法。这是什么工具 ActiveJob ( https://edgeguides.rubyonrails.org/active_job_basics.html )和sidekiq( https://github.com/mperham/sidekiq/ )是专为。
ActiveJob
例如,设计您的应用的方式是用户点击某个按钮上传CSV并回复:“感谢您的提交,我们正在努力!”。用户可以随时返回并检查正在处理的文件的状态或刷新屏幕。或者,您可以使用AJAX轮询或通过websockets进行双向通信来获得更复杂和自动化的状态检查。 Railsy这样做的方法就是用 ActionCable ( https://guides.rubyonrails.org/action_cable_overview.html )。
ActionCable