【问题标题】:MongoDB 2d compound index scanning many more documents than returnedMongoDB 2d 复合索引扫描的文档多于返回的文档
【发布时间】:2018-12-15 08:46:30
【问题描述】:

我有以下格式的数据:

{_id: ObjectId('...'), pos: [100, 100], uid: null}
{_id: ObjectId('...'), pos: [150, -100], uid: null}
{_id: ObjectId('...'), pos: [500, 137], uid: ObjectId('5b38d9876c08726511739141')}
{_id: ObjectId('...'), pos: [-980, 540], uid: uid: ObjectId('5b38d9876c08726511739141')}
...

我创建了以下索引:

{
    "v" : 2,
    "key" : {
        "pos" : "2d",
        "uid" : 1
    },
    "name" : "pos_2d_uid_1",
    "ns" : "coll.entities",
    "min" : -104857600,
    "max" : 104857600
}

然后我通过explain 运行以下查询:

db.coll.find({pos: {$geoWithin: {$box: [[-6949, 4064], [6408, -6468]]}}, uid: null});

并得到以下结果:

nReturned: 30
totalKeysExamined: 87753
totalDocsExamined: 87743

该集合中有大约 500k 个文档,因此它没有扫描整个集合(并且它正在使用“FETCH”阶段和正确的索引)。由于扫描了这么多文档,这些查询很慢,但是既然它正确匹配索引,为什么要扫描这么多文档而不是只扫描匹配的数字?

【问题讨论】:

  • 你能发布整个解释结果吗?

标签: mongodb indexing mongodb-query query-optimization


【解决方案1】:

我最终做的是完全取消地理空间查询,并用两个范围查询替换它,如下所示:

db.coll.find({uid: null, 'pos.0': {$gte: -6949, $lte: 6408}, 'pos.1': {$gte: -6468, $lte: 4064}});

然后我创建了以下索引:

{uid: 1, 'pos.0': 1, 'pos.1': 1}

此更改导致 totalDocsExamined 匹配 nReturned,这大大降低了 MongoDB 服务器上的负载。

【讨论】:

    猜你喜欢
    • 2015-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    相关资源
    最近更新 更多