【发布时间】:2013-12-15 15:48:48
【问题描述】:
在查询同一文档的两个字段时,我创建了 4 个索引来测试我的集合中的查询性能,其中一个是数组(需要多键索引)。其中两个索引是单一的,两个是复合的。
我很惊讶,因为使用单一索引之一比使用复合索引获得更好的性能。我期望使用复合索引获得最佳性能,因为我知道它索引了两个字段,从而可以更快地查询。
这些是我的索引:
{ "v" : 1,
"key" : { "_id" : 1 },
"ns" : "bt_twitter.mallorca.mallorca",
"name" : "_id_"
},
{ "v" : 1,
"key" : { "epoch_creation_date" :1 },
"ns" : "bt_twitter.mallorca.mallorca",
"name" : "epoch_creation_date_1"
},
{ "v" : 1,
"key" : { "related_hashtags" : 1 },
"ns" : "bt_twitter.mallorca.mallorca",
"name" : "related_hashtags_1"
},
{ "v" : 1,
"key" : { "epoch_creation_date" : 1, "related_hashtags" : 1 },
"ns" : "bt_twitter.mallorca.mallorca",
"name" : "epoch_creation_date_1_related_hashtags_1"
}
我的查询和性能指标是(提示参数显示每次查询使用的索引):
问题 1:
active_collection.find(
{'epoch_creation_date': {'$exists': True}},
{"_id": 0, "related_hashtags":1}
).hint([("epoch_creation_date", ASCENDING)]).explain()
毫:237
nscanned: 101226
问题 2:
active_collection.find(
{'epoch_creation_date': {'$exists': True}},
{"_id": 0, "related_hashtags": 1}
).hint([("related_hashtags", ASCENDING)]).explain()
毫:1131
nscanned: 306715
问题 3:
active_collection.find(
{'epoch_creation_date': {'$exists': True}},
{"_id": 0, "related_hashtags": 1}
).hint([("epoch_creation_date", ASCENDING), ("related_hashtags", ASCENDING)]).explain()
毫:935
nscanned: 306715
问题 4:
active_collection.find(
{'epoch_creation_date': {'$exists': True}},
{"_id": 0, "related_hashtags": 1}
).hint([("related_hashtags", ASCENDING),("epoch_creation_date", ASCENDING)]).explain()
毫:1165
nscanned: 306715
QUERY 1 扫描的文档较少,可能是什么原因扫描得更快。有人可以帮我理解为什么它比使用复合索引的查询执行得更好吗?那么,什么时候使用复合索引比使用单一索引更好?
我正在阅读 mongo 文档,但这些概念让我难以消化。
提前致谢。
更新的问题(针对 Sammaye 和 Philipp)
这是一个完整的explain()的结果
"cursor" : "BtreeCursor epoch_creation_date_1",
"isMultiKey" : false,
"n" : 101226,
"nscannedObjects" : 101226,
"nscanned" : 101226,
"nscannedObjectsAllPlans" : 101226,
"nscannedAllPlans" : 101226,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 242,
"indexBounds" : {u'epoch_creation_date': [[{u'$minElement': 1}, {u'$maxElement': 1}]]
},
"server" : "vmmongodb:27017"
对于以下查询:
active_collection.find(
{'epoch_creation_date': {'$exists': True}},
{"_id": 0, "related_hashtags":1})
.hint([("epoch_creation_date", ASCENDING)]).explain()
【问题讨论】:
-
您需要告诉我们这些索引是如何定义的。
-
嗨 Phillipp,您的意思是我是如何创建索引的?我以 active_collection.create_index([("epoch_creation_date", ASCENDING),("related_hashtags", ASCENDING)]) 为例
-
我的意思是你用来创建索引的 ensureIndex 调用。
-
嗯,再看一次查询 2 没有任何意义,为什么它与查询 3 和查询 4 相同的 nscanned,实际上没有理由为什么查询 4 应该与查询 3 具有相同的 nscanned跨度>
-
正如@Philipp 所说,您实际拥有哪些索引?
标签: python mongodb indexing multikey