上面的介绍使你惊叹于索引的强大作用,但要提醒你,不是所有查询都可以用索引 的。比如,在刚才的例子中,要是需要返回集合中90% 的文档而非获取一些记录, 就不应该用索引。

如果对这种查询用了索引,结果就是几乎遍历整个索引树,把其中一部分,比方说 60 GB 的索引都加载到内存。然后按照索引中的指针加载集合中230 GB 的文档数 据。最终将加载230 GB + 60 GB =290 GB,比不用索引还多。

所以,索引一般用在返回结果只是总体数据的一小部分的时候。根据经验,一旦要 大约返回集合一半的数据就不要使用索引了。

若是已经对某个字段建立了索引,又想在大规模查询时不使用它(因为使用索引可能 会较低效),可以使用自然排序,用{"$natural" : 1} 来强制MongoDB 禁用索引。 自然排序就是“按照磁盘上的存储顺序返回数据”,这样MongoDB 就不会使用索引了:

db.foo.find().sort({"$natural" : 1})

如果某个查询不用索引,MongoDB 会做全表扫描,即逐个扫描文档,遍历整个集 合,以找到结果。

写入速度

每当增加、删除、更新记录,所有相应的索引也必须更新。插入文档时,MongoDB 需要找到文档中的值在每一个索引树中的位置,然后在那儿插入。删除时,要找到 树中的索引项并删除。更新时,也可能像插入时那样新建索引项,也可能像删除时 那样删除索引项,若是值更新了就会既有添加又有删除。所以,索引会增加很多额 外的写入。