python - 为什么在两个键的查询中单个索引比复合索引更快? (MongoDB,多键)

标签 python mongodb indexing multikey

当查询同一文档的两个字段时,我创建了 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

扫描次数:101226

查询 2:

active_collection.find(
    {'epoch_creation_date': {'$exists': True}}, 
    {"_id": 0, "related_hashtags": 1}
).hint([("related_hashtags", ASCENDING)]).explain()

毫利斯:1131

扫描次数: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

扫描次数: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

扫描次数:306715

QUERY 1 扫描的文档较少,这可能是速度更快的原因。有人可以帮助我理解为什么它比使用复合索引的查询性能更好吗?因此,什么时候使用复合索引比使用单一索引更好?

我正在阅读 mongo 文档,但这些概念让我很难消化。

提前致谢。

更新的问题(回应 Sammaye 和 Philipp)

这是完整解释()的结果

"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()

最佳答案

您创建了一个复合索引(名为 epoch_creation_date_1_lated_hashtags_1),但您没有在这些提示中使用它。相反,您以不同的顺序使用您还创建的两个单字段索引(lated_hashtags_1epoch_creation_date_1)。

在这两个索引中,只有 epoch_creation_date_1 有效,因为您没有查询这两个字段。您仅查询一个,即 'epoch_creation_date': {'$exists': True}。您使用 {"_id": 0, "lated_hashtags":1} 执行的字段过滤是针对该查询找到的文档完成的。到那时,索引就没有任何用处了。这意味着 lated_hashtags 上的任何索引都无法提高此查询的性能。复合索引(当您实际使用它时)可能比没有索引好,但不如仅在 epoch_creation_date 上的索引。

关于python - 为什么在两个键的查询中单个索引比复合索引更快? (MongoDB,多键),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20285906/

相关文章:

python - 如何在 Flask 模板中解析和渲染 json

python - Whoosh 有多快?

python - 日期时间行为类型错误: parser() missing 1 required positional argument:

python - 如何从数据框中提取父节点和后续节点

sql - PostgreSQL 是否支持 "accent insensitive"排序规则?

sql - 对表建立索引以获得更好的查询性能

javascript - AngularJS ng-if 中的无限循环

mongodb - Mgo 聚合管道 $not 运算符。未知的顶级运算符(operator)

c# - 无法从 IMongoQueryable mongodb C# 驱动程序 linq 语句上的 GroupBy 中的组获取​​组项目

C: *数组[x]的大小?