简而言之:一个包含超过1600万条记录的表[大小为2GB].使用ORDER BY*primary_key时,使用SELECT的LIMIT偏移越高,查询变得越慢
所以
SELECT * FROM large ORDER BY `id` LIMIT 0, 30
Run Code Online (Sandbox Code Playgroud)
远远不及
SELECT * FROM large ORDER BY `id` LIMIT 10000, 30
Run Code Online (Sandbox Code Playgroud)
这也只能订购30条记录.所以这不是ORDER BY的开销.
现在,当获取最新的30行时,大约需要180秒.如何优化该简单查询?
我需要使用Rails获取上一个和下一个活动记录对象.我做到了,但不知道这是否是正确的方法.
我得到了什么:
控制器:
@product = Product.friendly.find(params[:id])
order_list = Product.select(:id).all.map(&:id)
current_position = order_list.index(@product.id)
@previous_product = @collection.products.find(order_list[current_position - 1]) if order_list[current_position - 1]
@next_product = @collection.products.find(order_list[current_position + 1]) if order_list[current_position + 1]
@previous_product ||= Product.last
@next_product ||= Product.first
Run Code Online (Sandbox Code Playgroud)
product_model.rb
default_scope -> {order(:product_sub_group_id => :asc, :id => :asc)}
Run Code Online (Sandbox Code Playgroud)
所以,这里的问题是我需要进入我的数据库并获取所有这些ID以了解谁是前一个和下一个.
尝试使用gem order_query,但它对我不起作用,我注意到它进入数据库并按顺序获取所有记录,所以,这就是为什么我做了同样但只得到id.
我发现的所有解决方案都是简单的订单查询.按ID排序或类似优先级字段.
我想通过ActiveRecord获取下一个/上一个记录.应根据'updated_at'列的顺序检索记录.
模型的名称是'Youtube'.并且作为以下控制台,此代码无法获得正确的记录,我猜我的代码的想法似乎很糟糕,因为updated_at并不总是唯一的,因此某些记录可能具有相同的时间戳.
你如何以正确的方式获得下一个/上一个记录?
控制台下面说.
[57] pry(main)> Youtube.find(1000)
Youtube Load (0.5ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY updated_at DESC LIMIT 1 [["id", 1000]]
=> #<Youtube id: 1000, author_id: 2, category_label: nil, generated_by: 1, title: "Is Kenya Mall Shooting Over? Were Americans Among A...", video_id: "4T1szQIQcNI", created_at: "2013-09-30 18:31:21", updated_at: "2013-10-27 02:19:56", subtitles: nil>
[58] pry(main)> Youtube.find(1000).next
Youtube Load (0.6ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY …
Run Code Online (Sandbox Code Playgroud) ruby activerecord ruby-on-rails ruby-on-rails-3.2 rails-activerecord