【问题标题】:Optimizing Compound Mongo GeoSpatial Index优化复合 Mongo 地理空间索引
【发布时间】:2013-07-24 10:36:06
【问题描述】:

我有一个 MongoDB $within,看起来像这样:

db.action.find( { $and : [
    { actionType : "PLAY" },
    { 
        location : { 
            $within : { 
                $polygon : [ [ 0.0, 0.1 ], [ 0.0, 0.2 ] .. [ a.b, c.d ] ]
            } 
        }
    }
] } ).sort( { time : -1 } ).limit(50)

关于动作集合文档

  • 有 5 种 actionType
  • 对于 PLAY 操作,操作文档可能有也可能没有一个比例约为 70:30 的位置
  • 否则没有位置
  • 行动文件总是有时间的

该集合包含以下索引

# I am interested recent actions 
db.action.ensureIndex({"time": -1}          

# I am interested in recent actions by a specific user
db.action.ensureIndex({"userId" : 1}, "time" -1}    

# I am interested in recent actions that relate to a unique song id
db.action.ensureIndex({"songId" : 1}, "time" -1}    

我正在试验以下两个索引

  • 仅限位置:db.action.ensureIndex({"location":"2d"})
  • 位置加时间:db.action.ensureIndex({"location":"2d"}, { "time": -1})

每个索引的相同查询解释如下:

仅限位置

{
    "cursor":"BasicCursor",
    "isMultiKey":false,
    "n":50,
    "nscannedObjects":91076,
    "nscanned":91076,
    "nscannedObjectsAllPlans":273229,
    "nscannedAllPlans":273229,
    "scanAndOrder":true,
    "indexOnly":false,
    "nYields":1,
    "nChunkSkips":0,
    "millis":1090,
    "indexBounds":{},
    "server":"xxxx"
}

位置加时间

{
    "cursor":"BasicCursor",
    "isMultiKey":false,
    "n":50,
    "nscannedObjects":91224,
    "nscanned":91224,
    "nscannedObjectsAllPlans":273673,
    "nscannedAllPlans":273673,
    "scanAndOrder":true,
    "indexOnly":false,
    "nYields":44,
    "nChunkSkips":0,
    "millis":1156,
    "indexBounds":{},
    "server":"xxxxx"
}

给定

  • 地理搜索将涵盖所有类型的文档
  • 地理搜索将以大约 60:40 的比例覆盖 NO Location 和 WITH Location 的文档

我的问题是

  • 谁能解释一下为什么第二个解释计划中的 isMultiKey="false" ?
  • 谁能解释为什么第二个解释计划的收益率更高?

我的猜测是

  • NULL 位置的可能性正在降低 地理空间索引。
  • GeoSpatial 种类的复合索引不如标准复合索引强大。

更新 示例文档如下所示。

{ "_id" : "adba1154f1f3d4ddfafbff9bb3ae98f2a50e76ffc74a38bae1c44d251db315d25c99e7a1b4a8acb13d11bcd582b9843e335006a5be1d3ac8a502a0a205c0c527", 
  "_class" : "ie.soundwave.backstage.model.action.Action", 
  "time" : ISODate("2013-04-18T10:11:57Z"),
  "actionType" : "PLAY",
  "location" : { "lon" : -6.412839696767714, "lat" : 53.27401934563561 },
  "song" : { "_id" : "82e08446c87d21b032ccaee93109d6be", 
             "title" : "Motion Sickness", "album" : "In Our Heads", "artist" : "Hot Chip"
           }, 
  "userId" : "51309ed6e4b0e1fb33d882eb", "createTime" : ISODate("2013-04-18T10:12:59.127Z") 
}

更新 地理查询看起来像这样 https://www.google.com/maps/ms?msid=214949566612971430368.0004e267780661744eb95&msa=0&ll=-0.01133,-0.019226&spn=0.14471,0.264187

由于各种原因,我们的数据库在 0.0 点存在大约 250,000 个文档

【问题讨论】:

  • 在任何一种情况下,您实际上都不会使用索引,因为您使用的是“BasicCursor” - 您也可以分享文档的外观吗?其他一些cmets:您不需要使用$and,因为这是默认设置,通常您希望使用2dsphere 索引而不是2d,因为它要快得多——您需要MongoDB 2.4虽然
  • 很有趣,谢谢 Derick。我更新了一个示例文档。我不确定 2dsphere 相对于 2d 的确切好处,所以我会先尝试一下。我不确定我是否完全理解您的“BasicCursor”评论。
  • BasicCursor 表示根本没有使用索引……我明天好好看看。
  • 看起来直到版本 2.5.1 2dsphere 不尊重“稀疏”选项 - 这看起来很有用,因为并非所有“动作”都有位置。 jira.mongodb.org/browse/SERVER-9639
  • 添加到上面描述的实际地理查询中。

标签: mongodb optimization indexing geo


【解决方案1】:

我玩了几天,得到了我想要的结果。

首先,鉴于“PLAY”以外的动作类型不能有位置,额外的查询参数“actionType==PLAY”是不必要的并被删除。我立即从“time-reverse-b-tree”光标切换到“Geobrowse-polygon”,我的测试搜索延迟提高了 10 个数量级。

接下来,我按照 Derick 的建议重新访问了 2dsphere。再次延迟大约 5 倍。总体而言,实现了更好的地图搜索用户体验。

我还剩下一个改进。在连续几天没有播放的区域中,查询的延迟通常会增加。这是因为查询会及时回溯,直到它可以找到“一些游戏”。如有必要,我将添加时间范围保护,以将这些查询的搜索空间限制为设定的天数。

感谢德里克的提示。

【讨论】:

    猜你喜欢
    • 2014-05-29
    • 1970-01-01
    • 2013-02-04
    • 2016-02-12
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    相关资源
    最近更新 更多