Mongoid to Mongo query translation
此问题已通过更简单的说明进行了更新。
对于我的数据,以下Mongo CLI查询需要208毫秒。此查询检索18个请求的对象的所有数据。
db.videos.find({avg_rating:{$ gt:1},poster_large_thumb:{$ exists:true},release_date:{$ lte:ISODate(" 2000-12-31 ")}})。 sort({release_date:-1,avg_rating:-1,title:1})。skip(30).limit(18).pretty()。explain()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | { "cursor" :"BasicCursor", "nscanned" : 76112, "nscannedObjects" : 76112, "n" : 48, "scanAndOrder" : true, "millis" : 208, "nYields" : 0, "nChunkSkips" : 0, "isMultiKey" : false, "indexOnly" : false, "indexBounds" : { } } |
但是对于Mongoid,当我执行查询时,它会创建一个没有实际数据的条件对象。我将此条件传递给一种方法,以对其进行迭代以创建JSON数据结构。由于需要数据,因此必须从数据库中检索每个对象。以下是返回查询的条件:
@videos = Video.order_by(发布日期:-1,avg_rating:-1,标题:1).where(:avg_rating.gt => 1,:poster_large_thumb.exists => 1,1,:release_date.lte => start_date )。跳过(跳过* POSTERS_PER_ROW).limit(限制* POSTERS_PER_ROW)
当我迭代@videos时,每个对象都需要240毫秒以上的时间才能从DB中检索到,这是从某些调试输出中检索出来的。
1 2 3 4 | Getting one object: 2013-12-18 00:43:52 UTC 2013-12-18 00:43:52 UTC 0.24489331245422363 |
假设如果我在Video.order_by(...)查询中获得了所有数据,则总共要花费208ms,如何强制它在一个查询中进行检索,而不是单独获取每个对象?
此处的某些原因导致整个检索比Mongo CLI多花费几个数量级。
响应:
skip()。limit()查询在MongoDB方面会越来越慢。跳过文档时,请参阅此处的更多信息https://stackoverflow.com/a/7228190/534150
多个相同的查询在我看来是N 1类型的问题。这意味着可能在您的视图中的某个地方,您有一个循环调用一个延迟加载的属性,因此它会反复发送查询。这些问题通常很难发现,但是要跟踪它们,您需要进行端到端跟踪,因为您可以访问源代码,所以您可能是唯一可以做到这一点的跟踪器。
对我来说,Mongoid一侧看起来很正确。
感谢您的想法,我认为@Arthur提供了重要提示。没有人可以回答,因为看起来问题出在另一段代码中,即我访问标准的方式。
给出以下查询,该查询将产生一个条件:
1 | @videos = Video.order_by(release_date: 1, avg_rating: 1, title: -1).where(:release_date.ne => 0,:avg_rating.gt => 1, :poster_large_thumb.exists => 1, :release_date.gt => start_date).skip(skip*POSTERS_PER_ROW).limit(limit*POSTERS_PER_ROW).only(:_id, :poster_large_thumb, :title) |
在几个嵌套块中,我使用如下代码行来获取值:
1 | video_full = @videos[((row_index)*POSTERS_PER_ROW)+column_index] |
此随机访问符号似乎是问题所在。似乎对每个单个对象执行完整的Moped查询,因此POSTERS_PER_ROW * num_rows次。
如果我使用以下代码在循环之前抓取所有视频:
1 2 3 | @videos.each do |video| videos_full.push video end |
然后从数组中获取值,而不是像这样的条件:
1 | video_full = videos_full[((row_index)*POSTERS_PER_ROW)+column_index] |
我只收到一个248ms的Moped查询,所有的对象都通过该查询来检索。这是一个巨大的速度。查询时间从num_rows * POSTERS_PER_ROW * 248ms变为248ms
这对我来说是一个重要的教训,因此,如果有人可以指向描述此效果的文档以及要遵循的规则,我将不胜感激。