【发布时间】:2017-12-18 23:04:13
【问题描述】:
跟进我的问题here,我正在尝试进一步改进搜索。我们首先搜索一个回放表(搜索 2k 条记录),然后获取与该表关联的唯一玩家(每 10 个,因此 20k 条记录)并呈现 JSON。这是通过控制器完成的,搜索内容为:
def index
@replays = Replay.includes(:players).where(map_id: params['map_id'].to_i).order(id: :desc).limit(2000)
render json: @replays[0..2000].to_json(include: [:players])
end
表现:
Completed 200 OK in 254032ms (Views: 34.1ms | ActiveRecord: 20682.4ms)
实际的 Active Record 搜索如下:
Replay Load (80.4ms) SELECT "replays".* FROM "replays" WHERE "replays"."map_id" = $1 ORDER BY "replays"."id" DESC LIMIT $2 [["map_id", 1], ["LIMIT", 2000]]
Player Load (20602.0ms) SELECT "players".* FROM "players" WHERE "players"."replay_id" IN (117217...
这主要是有效的,但仍然需要非常多的时间。有没有办法提高性能?
【问题讨论】:
-
只是一个快速的仅供参考(正如我按照上一个问题进行的那样) - 现在您不需要
index第二行上的 [0..2000]。limit@GustavMauler 对此进行了介绍。 -
是的,对不起。我从来没有真正做过一个数据量这么大(大多较小)的个人项目,所以额外的 [0..2000](除了冗余)会对性能有那么大的影响吗?
-
应该不会有太大影响 - 最好事先限制查询,因为它会减少对数据库的要求。这可能是我的新答案的失败 :) 不过,在您的代码中这绝对是多余的,并且实际上还会为您提供 2,001 条记录,因为它从 0 开始计数。
-
我想知道为什么第二个查询需要这么长时间?数据库列上是否缺少索引?还是有太多玩家无法记忆?返回的 JSON 有多大?
-
这绝对是索引问题。 json 相当大(2k 重播 = 20k 玩家),但还没有到应该花这么长时间的地步。
标签: ruby-on-rails ruby postgresql activerecord