我在MongoDB中有一个大约110万条记录的集合。平均对象大小为7.4kb,因此数据库大约为8GB。我有一个解析整个集合的应用程序,但必须在每个记录中的endsAt日期同步排序。同样重要的是,这些不是现场游戏(isLive:false),因为否则结束日期不会存在。一旦解析了记录,为了确保它不被再次拉入,我将isComplete:true的值设置为记录。
现在因为数据必须根据endsAt日期最早返回给我,所以我在集合上运行sort()函数。这对我来说似乎是一个巨大的瓶颈。
我要查询下一个要解析的X行(请记住,这些需要同步)的查询如下:
db.matches.find({ isComplete: { $exists: false }, isLive: false }).limit(n)
当n只是5时,查询的速度是: 的 0.22s
但是,当我向同一个查询添加必要的排序时,因为我绝对必须在最早的截止日期之前返回接下来的n行(如果它们尚未被解析),查询时间会大大增加到: 的 46.5s
奇怪的是,我设法解决了几十万个没有问题的游戏,并且查询变得越来越慢,直到现在它们实际上超时了。对于大多数人来说,这听起来像是一个索引问题,但是我在以下字段中有索引:
idx_startedAt (1)
idx_endedAt (1)
idx_isComplete (1)
idx_isLive (1)
我不确定我还应该将其编入索引以提高此查询的速度,但我对如何最好地解决此问题感到十分迷茫。任何帮助,总是非常感激。
答案 0 :(得分:0)
您需要使用compound index对所有过滤条件编制索引,包括sort。
仅过滤单个字段仍需要从磁盘扫描大量文档,然后将结果排序到内存中。索引所有字段(包括排序)将最大限度地减少从磁盘读取的文档数量,并且无需在内存中对结果进行排序。
此查询的理想索引如下:
<div class="slide active-slide">
<h3>Question 1: Answer is A! </h3>
<input type="radio" name="q1" value="correct">A</input><br>
<input type="radio" name="q1" value="incorrect">B</input><br>
<input type="radio" name="q1" value="incorrect">C</input><br>
<input type="radio" name="q1" value="incorrect">D</input>
<input type="button" class="btnNext" value="Next">
</div>
<div class="slide">
<h3>Question 2: Answer is B! </h3>
<input type="radio" name="q2" value="incorrect">A</input><br>
<input type="radio" name="q2" value="correct">B</input><br>
<input type="radio" name="q2" value="incorrect">C</input><br>
<input type="radio" name="q2" value="incorrect">D</input>
<input type="button" class="btnNext" value="Next">
</div>