繁体   English   中英

MongoDB查询花费太多时间来检索数据

[英]MongoDB query taking too much time to retrieve data

我有一个集合,其中包含300万份文档和以下索引:

{ts:1},{u_id:1}

请注意,这是两个单独的升序索引,而不是复合索引。

当我运行此查询时:

db.collection.find({u_id:'user'})。sort({ts:-1})。skip(0).limit(1)

需要100毫秒。 我有以下日志:

2017-04-15T06:42:01.147 + 0000 I COMMAND [conn783]查询
db.collection查询:{orderby:{ts:-1},$ query:{
u_id:“ user-ki-id}} planSummary:IXSCAN {u_id:
1},IXSCAN {u_id:1} ntoreturn:1 ntoskip:0 keysExamined:10795
docsExamined:10795 hasSortStage:1 cursorExhausted:1键更新:0
writeConflicts:0 numYields:86 nreturned:1 reslen:771 locks:{Global:{
acquisitionCount:{r:174}},数据库:{acquisitionCount:{r:87}},
集合:{AccountCount:{r:87}}} 246ms

有关该问题的一些值得注意的点:

  • MongoDB上没有其他负载,即没有其他查询花费+ 100ms
  • 这每分钟都会发生。 我想我每分钟都会存储数据,所以这种情况正在发生
  • 查询流程是首先运行读取的查询(如上所述),然后下一个查询是批量插入。 每隔一分钟重复一次此流程。

所以我的问题是:

  • 为什么会这样呢? 我的索引是否存在设计缺陷?
  • 可能值得将索引更改为降序,例如{ts:-1}? 这些指标之间的实际区别是什么?
  • 根据MongoDB文档,当您按顺序进行排序时,结果将从磁盘而不是“内存中”中选取。 这是否解释了为什么需要100ms的时间?
  • 有人可以详细解释我的配置日志吗?
  • 它是MongoDB的理想行为吗?

当我对该集合进行范围搜索时,也会发生同样的事情。 这需要3-5秒。

编辑:我只添加了{u_id:1,ts:-1}索引。 删除所有其他索引(_id除外)。 仍然是第一次执行查询需要100毫秒以上的时间。 这不应该发生。
查询:

db.getCollection('locations').find({u_id:“ USR-WOWU”}).sort({ts:-1}).explain(true)

输出::

/ * 1 * / {“ queryPlanner”:{“ plannerVersion”:1,“命名空间”:“ db_name.collection_name”,“ indexFilterSet”:false,“ parsedQuery”:{“ user_id”:{“ $ eq”:“ USR -WOWU“}},” winningPlan“:{” stage“:” FETCH“,” inputStage“:{” stage“:” IXSCAN“,” keyPattern“:{” u_id“:1.0,” ts“:-1.0} ,“ indexName”:“ u_id_1_ts_-1”,“ isMultiKey”:false,“ isUnique”:false,“ isSparse”:false,“ isPartial”:false,“ indexVersion”:1,“ direction”:“ forward”,“ indexBounds“:{” u_id“:[” [\\“ USR-WOWU \\”,\\“ USR-WOWU \\”]“],” ts“:[” [MaxKey,MinKey]“]}}},” rejectedPlans“ :[]},“ executionStats”:{“ executionSuccess”:true,“ nReturned”:164,“ executionTimeMillis”:119,“ totalKeysExamined”:164,“ totalDocsExamined”:164,“ executionStages”:{“ stage”:“ FETCH”, “ nReturned”:164, “ executionTimeMillisEstimate”:120, “ works”:165,“ advanced”:164,“ needTime”:0,“ needYield”:0,“ saveState”:3,“ restoreState”:3 ,“ isEOF”:1,“无效”:0,“ docsExamined”:164,“ alreadyHasObj”:0, “ inputStage”:{“ stage”:“ IXSCAN”,“ nReturned”:164,“ executionTimeMillisEstimate”:0,“ works”:165,“ advanced”:164,“ needTime”:0,“ needYield”:0,“ saveState”:3,“ restoreState”:3,“ isEOF”:1,“ invalidates”:0,“ keyPattern”:{“ u_id”:1.0,“ ts”:-1.0},“ indexName”:“ u_id_1_ts_-1 “,” isMultiKey“:否,” isUnique“:否,” isSparse“:否,” isPartial“:否,” indexVersion“:1,” direction“:” forward“,” indexBounds“:{” u_id“:[ “ [\\” USR-WOWU \\“,\\” USR-WOWU \\“]”],“ ts”:[“ [MaxKey,MinKey]”]},“ keysExamined”:164,“ dupsTested”:0,“ dupsDropped “:0,” seenInvalidated“:0}},” allPlansExecution“:[]},” serverInfo“:{” host“:” manish“,” port“:22022,” version“:” 3.2.13“,” gitVersion“:” 23899209cad60aaafe114f6aea6cb83025ff51bc“},“确定”:1.0}

请复制以上jSON并将其格式化为任何编辑器。

完成上述查询后,下一个相同的查询将在约2毫秒内响应。 但是,当我很少插入时,一分钟后将重复同样的事情。 (第一次查询将花费时间+ 100ms,然后大约需要2ms。)

在我的mongoDB中是否缺少某些东西或需要任何配置?

为什么会这样

此日志行的docsExamined:10795hasSortStage:1部分指示查询正在从磁盘扫描10,795,然后对内存中的结果进行排序。 可以在此处找到有关解释日志行的指南。

通过索引此查询以避免内存中排序,可能会提高性能。

对于此查询,您应该尝试创建索引{ 'u_id' : 1, 'ts' : -1 }

如果我将降序更改为{ts:-1}之类的索引,真的值得吗?

索引可以从任何方向读取,因此索引顺序在单字段索引上并不是很重要。 但是,排序顺序在复合索引中可能非常重要。

更新

根据解释计划,查询现在可以正确地使用索引从索引中按顺序读取结果,从而避免了内存中排序。 看起来这使查询缩短了〜100ms。

但是,看起来此查询不再使用.skip(0).limit(1) 您可以重新添加这些,看看性能是否有所提高?

您的部署似乎没有任何问题。 对于未完全索引的查询,此行为似乎很正常。

重新运行完全相同的查询将很快,因为现有结果(“ 工作集 ”)已经存储在内存中。 插入新数据可以使查询结果发生变化,这意味着可能需要再次将结果读回到内存中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM