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

时间:2017-05-04 23:08:35

标签: mongodb performance

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

  

{ts:1},{u_id:1}

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

当我运行此查询时:

  

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

需要+ 100ms。我有以下日志:

  

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 keyUpdates:0
  writeConflicts:0 numYields:86 nreturned:1 reslen:771 locks:{Global:{
  acquireCount:{r:174}},数据库:{acquireCount:{r:87}},
  收集:{acquireCount:{r:87}}} 246ms

关于这个问题的一些值得注意的要点:

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

所以我的问题是:

  • 为什么会这样?我的索引中有任何设计缺陷吗?
  • 将索引更改为降序可能值得{ts:-1}吗?这些指数之间的实际差异是什么?
  • 根据MongoDB文档,当您使用订单进行排序时,结果将从磁盘中选择而不是"在内存中#34;。这是否解释了为什么需要+ 100ms?
  • 有人可以解释一下我在详细记录详细程度吗?
  • 是否需要MongoDB的行为?

当我在这个集合上运行范围搜索时,也会发生同样的事情;这需要3-5秒。

修改 我只添加{u_id:1,ts:-1}索引。删除所有其他索引(_id除外)。仍然在第一次执行查询执行+ 100毫秒。这不应该发生 查询:

  

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

OutPut ::

  

/ * 1 * / {       " queryPlanner" :{           " plannerVersion" :1,           "命名空间" :" db_name.collection_name",           " indexFilterSet" :假的,           " parsedQuery" :{               " USER_ID" :{                   " $当量" :" USR-WOWU"               }           },           " winningPlan" :{               "级" :" FETCH",               " inputStage" :{                   "级" :" IXSCAN",                   " keyPattern" :{                       " U_ID" :1.0,                       " TS" :-1.0                   },                   " INDEXNAME" :" u_id_1_ts_-1",                   " isMultiKey" :假的,                   " isUnique设置" :假的,                   " isSparse" :假的,                   " isPartial" :假的,                   " indexVersion" :1,                   "方向" :"转发",                   " indexBounds" :{                       " U_ID" :[                           " [\" USR-WOWU \",\" USR-WOWU \"]"                       ]                       " TS" :[                           " [MaxKey,MinKey]"                       ]                   }               }           },           " rejectedPlans" :[]       },       " executionStats" :{           " executionSuccess" :真的,           " nReturned" :164,           " executionTimeMillis" :119,           " totalKeysExamined" :164,           " totalDocsExamined" :164,           " executionStages" :{               "级" :" FETCH",               的" nReturned" :164,               的" executionTimeMillisEstimate" :120,               "工作" :165,               "高级" :164,               " needTime" :0,               " needYield" :0,               " saveState和" :3,               " restoreState" :3,               " isEOF" :1,               "无效信号" :0,               " docsExamined" :164,               " alreadyHasObj" :0,               " inputStage" :{                   "级" :" IXSCAN",                   " nReturned" :164,                   " executionTimeMillisEstimate" :0,                   "工作" :165,                   "高级" :164,                   " needTime" :0,                   " needYield" :0,                   " saveState和" :3,                   " restoreState" :3,                   " isEOF" :1,                   "无效信号" :0,                   " keyPattern" :{                       " U_ID" :1.0,                       " TS" :-1.0                   },                   " INDEXNAME" :" u_id_1_ts_-1",                   " isMultiKey" :假的,                   " isUnique设置" :假的,                   " isSparse" :假的,                   " isPartial" :假的,                   " indexVersion" :1,                   "方向" :"转发",                   " indexBounds" :{                       " U_ID" :[                           " [\" USR-WOWU \",\" USR-WOWU \"]"                       ]                       " TS" :[                           " [MaxKey,MinKey]"                       ]                   },                   " keysExamined" :164,                   " dupsTested" :0,                   " dupsDropped" :0,                   " seenInvalidated" :0               }           },           " allPlansExecution" :[]       },       " serverInfo" :{           "主机" :" manish",           "端口" :22022,           "版本" :" 3.2.13",           " gitVersion" :" 23899209cad60aaafe114f6aea6cb83025ff51bc"       },       " OK" :1.0}

请将以上jSON和格式复制到任何编辑器中。

在上述查询之后,下一个相同的查询将在~2 ms内响应。但是当我进行少量插入时,一分钟之后会重复同样的事情。 (第一次查询需要时间+ 100ms,然后需要~2ms。)

在我的mongoDB中配置是否缺少或需要配置什么?

1 个答案:

答案 0 :(得分:2)

  

为什么会这样?

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

indexing this query to avoid the in-memory sort可能会提高绩效。

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

  

如果我按降序改变{ts:-1}之类的索引,那真的是值得的。

可以在任一方向读取索引,因此索引顺序对单个字段索引不是非常重要。但是,排序顺序在compound indexes中非常重要。

更新

根据解释计划,查询现在正确使用索引按顺序读取索引中的结果,这样可以避免内存中的排序。看起来这个问题已经被淘汰了大约100毫秒。

但是,此查询似乎不再使用.skip(0).limit(1)。您可以重新添加这些并查看性能是否有所改善?

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

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