mongodb:会限制()提高查询速度吗?

时间:2015-07-01 13:26:59

标签: mongodb

db.inventory.find().limit(10)db.inventory.find()更快吗?

我在mongodb有数百万条记录,我希望在某些订单中获得前10名记录。

2 个答案:

答案 0 :(得分:2)

使用limit()通知服务器您不会检索超过 k 的文档。允许一些优化以减少带宽消耗并加速排序。最后,使用限制子句,服务器将能够更好地使用在RAM中排序时可用的32MB最大值(即:当无法从索引获取排序顺序时)。

现在,长篇故事:find()返回一个光标。默认情况下,光标会将结果批量传输到客户端。来自the documentation,:

  

对于大多数查询,第一批返回101个文档或只有足够的文档超过1兆字节。后续批量大小为4兆字节。

使用limit()光标不需要检索超过必要的文档。从而减少带宽消耗和延迟。

请注意,根据您的使用案例,您可能也会使用sort()操作。从上面的相同文档:

  

对于包含没有索引的排序操作的查询,服务器必须加载内存中的所有文档以在返回任何结果之前执行排序。

sort() documentation page进一步解释:

  

如果MongoDB无法通过索引扫描获得排序顺序,那么MongoDB使用top-k排序算法。此算法缓冲底层索引或集合访问到目前为止看到的前k个结果(或最后一个,具体取决于排序顺序)。如果在任何时候这些k结果的内存占用超过32兆字节,则查询将失败 1

1 该32 MB限制并非特定于使用limit()子句进行排序。无法从索引获得其顺序的任何类型都将受到相同的限制。但是,使用 plain 排序服务器需要在其内存中保存所有文档以对其进行排序。使用限制排序时,只需将 k 文档同时存储在内存中。

答案 1 :(得分:0)

如果您按顺序需要它,那么DB当然会先根据条件对其进行排序,然后返回前10条记录。通过使用限制,您只需节省网络带宽。例如在这里我按名称排序,然后给出前10条记录,它必须扫描整个数据,然后选择前10名。(你可以注意到它做了COLLSCAN,这是理解为收集扫描,因为我没有索引对于这个例子,这里显示的想法是它对所有记录进行全面扫描,对其进行排序,然后选择最顶层的记录。)

> db.t1.find().sort({name:1}).limit(10).explain()
{
    "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.t1",
            "indexFilterSet" : false,
            "parsedQuery" : {
                    "$and" : [ ]
            },
            "winningPlan" : {
                    "stage" : "SORT",
                    "sortPattern" : {
                            "name" : 1
                    },
                    "limitAmount" : 10,
                    "inputStage" : {
                            "stage" : "COLLSCAN",
                            "filter" : {
                                    "$and" : [ ]
                            },
                            "direction" : "forward"
                    }
            },
            "rejectedPlans" : [ ]
    },
    "serverInfo" : {
            "host" : "Sachin-Mac.local",
            "port" : 27017,
            "version" : "3.0.2",
            "gitVersion" : "6201872043ecbbc0a4cc169b5482dcf385fc464f"
    },
    "ok" : 1
}