数组字段上的MongoDB索引结果

数组字段上的MongoDB索引结果,mongodb,indexing,database-performance,Mongodb,Indexing,Database Performance,我有一个集合{学生id:1,教师:[“…”,…]} 按如下顺序完成的步骤:1)由{teachers:“gore}查找 2) 将索引设置为{student\u id:1} 3) 通过{教师:“戈尔”}查找 4) 将索引设置为{teachers:1} 5) 通过{教师:“戈尔”}查找 通过索引教师(数组),结果(花费的时间)并没有那么有效。请有人解释一下发生了什么?我可能做错了什么,请纠正我。结果如下: d、 查找({teachers:gore}).explain() {“cursor”:“Basi

我有一个集合{学生id:1,教师:[“…”,…]}

按如下顺序完成的步骤:1)由{teachers:“gore}查找

2) 将索引设置为{student\u id:1}

3) 通过{教师:“戈尔”}查找

4) 将索引设置为{teachers:1}

5) 通过{教师:“戈尔”}查找

通过索引教师(数组),结果(花费的时间)并没有那么有效。请有人解释一下发生了什么?我可能做错了什么,请纠正我。结果如下:

d、 查找({teachers:gore}).explain()

{“cursor”:“BasicCursor”,“nscanned”:999999,“nscannedObjects”:999999,“n”:447055,“millis”:1623,“nYields”:0,“nChunkSkips”:0,“isMultiKey”:false,“indexOnly”:false,“indexBounds”:{ }}

d、 ensureIndex({学生id:1})

d、 查找({teachers:“gore”})。explain(){“cursor”:“BasicCursor”,“nscanned”:999999,“nscannedObjects”:99999,“n”:447055,“millis”:1300,“nYields”:0,“nChunkSkips”:0,“isMultiKey”:false,“indexOnly”:false,“indexBounds”:{ }}

d、 ensureIndex({教师:1})


d、 查找({teachers:“gore”})。explain(){“cursor”:“BtreeCursor teachers_1”,“nscanned”:447055,“nscanned objects”:447055,“n”:447055,“millis”:1501,“nYields”:0,“nChunkSkips”:0,“isMultiKey”:true,“indexOnly”:false,“indexBounds”:{“teachers”:[“gore”,“gore”]}您是否反复插入相同的数据?显示BtreeCursor的事实是肯定的,但nscannedObjects的数量太多。您是否反复插入相同的数据?您是否有可能拥有447055个“戈尔”值?如果是这样的话,这就是为什么要花这么长时间的原因。

检查上一个解释结果,
“n”:447055
,这意味着这些文档被匹配并通过查询返回,所以这需要时间。我对毫秒的倒数第二和最后解释查询有一个问题,即在索引之前,它在1300毫秒内访问9999999个文档,而在索引之后,它只访问了一半的文档,仍然需要更多的时间,比第一次对返回的结果数量发表评论还要多1501毫秒。。如果值的范围不是很有选择性,索引将不会有多大帮助(并且可能会慢一些)。您的示例是在999999个文档中查找447055个匹配项,这几乎占集合的50%。在这个比率下,可以更快地读取整个集合并比较结果,而不是使用索引。一个有效的索引将允许查询通过读取更少的数据(相关的索引和数据)更快地缩小结果范围。同样值得注意的是:如果所有的数据和索引都已加载到内存中(并且总大小小于内存),那么后续查询的执行速度将更快。您应该在不使用
explain()
的情况下跨多个运行对查询计时,以了解有效查询时间——使用或经过的开始/停止时间。
explain()
includes的计时在正常查询使用中被缓存。@Stennie感谢您提供的信息,它帮助我理解了索引的使用。但我有一个要求,需要从学生id到教师数组和教师到学生id两种方式进行搜索,而且数据太大,所以查询应该运行得更快,是否有其他解决方案?是的,我的要求与我用于测试的结构相同。我也可能有超过50%的文档中包含教师