如果有,是哪一个?
我们怎么知道?
我在一个查询中有 3 个索引。实际上只有前两个应该有用
{
"v": NumberInt(1),
"key": {
"LongitudeLatitude": "2d",
"Prominent"▼: NumberInt(-1),
"indexContents": NumberInt(1)
},
"ns": "database.tablebusiness",
"name": "LongLat_Prominent_indexContents",
"dropDups": false,
"background": false
}
{
"v": NumberInt(1),
"key": {
"LongitudeLatitude": "2d",
"Prominent": NumberInt(-1)
},
"ns": "database.tablebusiness",
"name": "LongLat_Prominent",
"dropDups": false,
"background": false
}
这个不是必须的:
{
"v": NumberInt(1),
"key": {
"indexContents": NumberInt(1)
},
"ns": "database.tablebusiness",
"name": "indexContents",
"dropDups": false,
"background": false
}
现在我做这个查询
(查询来自 PhP,所以我只粘贴我在 mongodb 日志和 mongovue 中看到的内容
database.tablebusiness query: { LongitudeLatitude: { $nearSphere: [ 106.772835, -6.186753 ], $maxDistance: 0.04498373205078301 }, Prominent: { $gte: 15 }, indexContents: { $all: [ /^aru/, /^op/ ] } } ntoreturn:20 ntoskip:80 nscanned:100 nreturned:20 reslen:1147 1927ms
现在复制{ LongitudeLatitude: { $nearSphere: [ 106.772835, -6.186753 ], $maxDistance: 0.04498373205078301 }, Prominent: { $gte: 15 }, indexContents: { $all: [ /^aru/, /^op/ ] } }
到 mongovue find 命令让我得到真正的数据库命令
db.tablebusiness.find({ "LongitudeLatitude" : { "$nearSphere" : [106.772835, -6.186753], "$maxDistance" : 0.044983732050783008 }, "Prominent" : { "$gte" : 15 }, "indexContents" : { "$all" : [/^aru/, /^op/] } }).limit(50);
这已经足够好了(除了限制稍微改变了一点)。在 mongo.exe 中做解释我得到了
db.tablebusiness.find({ "LongitudeLatitude" : { "$nearSphere" : [106.772835, -6.186753], "$maxDistance" : 0.044983732050783008 }, "Prominent" : { "$gte" : 15 }, "indexContents" : { "$all" : [/^aru/, /^op/] } }).limit(50).explain();
{
"cursor" : "GeoSearchCursor",
"nscanned" : 50,
"nscannedObjects" : 50,
"n" : 50,
"millis" : 3291,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
现在基于此,使用什么索引?mongodb 是否使用任何索引?任何有关如何改进此查询的提示也将不胜感激。
您无法分辨正在使用哪个的原因是因为一个错误,其中解释不包括用于地理索引查询的索引的索引名称:
https://jira.mongodb.org/browse/SERVER-4213
我们所知道的是,它必须是您列出的前两个元素之一,首先具有 2d 元素。它不能是
"indexContents": NumberInt(1)
索引。您可以使用.hint()指定要使用的索引,然后在每种情况下比较索引的结果。我希望第一个总体上表现更好(但更大),因为它包含您正在查询的所有元素:"LongitudeLatitude": "2d", "Prominent"▼: NumberInt(-1), "indexContents": NumberInt(1)
但是,这将取决于实际数据本身。我会测试一组有代表性的查询,然后删除两个索引中较慢的一个以避免混淆。