提高MongoDB $ geoIntersects查询的性能

时间:2018-04-25 19:49:10

标签: mongodb performance indexing geospatial

我试图改进MongoDB查询,该查询按点查询文档。这些文档具有简单的多边形几何形状,其中10到100个点之间以及50到5000米之间。示例文档:

{
    "_id" : UUID("9175a387-4b0c-48ab-a74a-a8b200cc5285"),
    "seconds" : NumberLong(123),
    "geometry" : {
        "type" : "Polygon",
        "coordinates" : [ [ 
            [ 28.08093, -26.00869 ], 
            [ 28.09113, -26.01888 ], 
            [ 28.09486, -26.03282 ],  
            [ 28.08093, -26.00869 ] ]
        ]
    }
}

该查询使用$geoIntersects按点过滤,并按seconds对结果进行排序。几何和秒有一个地理空间索引,我测试过它在这个查询中得到了使用:

IXSCAN { geometry: "2dsphere", seconds: 1 }

当我们使用MongoDB C#驱动程序时,这不是确切的查询,而是我通过分析检索的内容,但查询的示例如下:

db.getCollection('fooCollection')
.find({
    "geometry" : {
        "$geoIntersects" : {
            "$geometry" : {
                "type" : "Point",
                "coordinates" : [ 28.04, -26.19 ]
            } } } })
.sort({ "seconds" : 1 })
.projection({ "geometry" : 0 })

由于我们只需要几何查询,我们还只投影id和seconds字段来减少数据I / O.几何是近似值,不一定是完美的匹配。

此查询在极其严重的性能关键任务中使用,它是一个瓶颈,需要大约170毫秒才能完成。这远远不如我们的其他Mongo查询那么快,通常在20-30ms端到端完成。

我对$geoIntersects查询或地理空间索引的内部知识不够了解,知道是否有任何方法可以提高此查询的性能。我不确定的一些(相当耗时)的想法值得追求:

  • 简化所有几何体以减少使用点数。

  • 使用比2dsphere更简单的参考几何体。对于我们的目的,平坦的近似值足够接近。

  • 核选项:缓存内存中的所有几何体并自行执行碰撞检测。这取决于编写像MongoDB一样高效的算法和索引查找。

这次手术有什么我想念的吗? 提高MongoDB $geoIntersects查询效果的最佳方法是什么?

编辑:根据要求添加了以下explain()输出:

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "fooCollection",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "geometry" : {
                "$geoIntersects" : {
                    "$geometry" : {
                        "type" : "Point",
                        "coordinates" : [ 
                            28.04, 
                            -26.19
                        ]
                    }
                }
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "filter" : {
                "geometry" : {
                    "$geoIntersects" : {
                        "$geometry" : {
                            "type" : "Point",
                            "coordinates" : [ 
                                28.04, 
                                -26.19
                            ]
                        }
                    }
                }
            },
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "geometry" : "2dsphere",
                    "seconds" : 1
                },
                "indexName" : "Geometry_Seconds",
                "isMultiKey" : true,
                "multiKeyPaths" : {
                    "geometry" : [ 
                        "geometry"
                    ],
                    "seconds" : []
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "geometry" : [ 
                        "[2202260217784172544, 2202260217784172544]", 
                        "[2203386117691015168, 2203386117691015168]", 
                        "[2203667592667725824, 2203667592667725824]", 
                        "[2233785415175766016, 2233785415175766016]"
                    ],
                    "seconds" : [ 
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : []
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 29,
        "executionTimeMillis" : 5,
        "totalKeysExamined" : 58,
        "totalDocsExamined" : 46,
        "executionStages" : {
            "stage" : "FETCH",
            "filter" : {
                "geometry" : {
                    "$geoIntersects" : {
                        "$geometry" : {
                            "type" : "Point",
                            "coordinates" : [ 
                                28.04, 
                                -26.19
                            ]
                        }
                    }
                }
            },
            "nReturned" : 29,
            "executionTimeMillisEstimate" : 0,
            "works" : 58,
            "advanced" : 29,
            "needTime" : 28,
            "needYield" : 0,
            "saveState" : 0,
            "restoreState" : 0,
            "isEOF" : 1,
            "invalidates" : 0,
            "docsExamined" : 46,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 46,
                "executionTimeMillisEstimate" : 0,
                "works" : 58,
                "advanced" : 46,
                "needTime" : 11,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "geometry" : "2dsphere",
                    "seconds" : 1
                },
                "indexName" : "Geometry_Seconds",
                "isMultiKey" : true,
                "multiKeyPaths" : {
                    "geometry" : [ 
                        "geometry"
                    ],
                    "seconds" : []
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "geometry" : [ 
                        "[2202260217784172544, 2202260217784172544]", 
                        "[2203386117691015168, 2203386117691015168]", 
                        "[2203667592667725824, 2203667592667725824]", 
                        "[2233785415175766016, 2233785415175766016]"
                    ],
                    "seconds" : [ 
                        "[MinKey, MaxKey]"
                    ]
                },
                "keysExamined" : 58,
                "seeks" : 12,
                "dupsTested" : 46,
                "dupsDropped" : 0,
                "seenInvalidated" : 0
            }
        }
    },
    "serverInfo" : {
        "host" : "LAPTOP-F7A8SNP5",
        "port" : 27017,
        "version" : "3.6.3",
        "gitVersion" : "9586e557d54ef70f9ca4b43c26892cd55257e1a5"
    },
    "ok" : 1.0
}

0 个答案:

没有答案