当前位置: 首页 > 知识库问答 >
问题:

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

郁灿
2023-03-14

我收集了300万份文件,索引如下:

{ts:1},{u\u id:1}

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

当我运行此查询时:

db.collection.find({u_id:'user'})。排序({ts:-1})。跳过(0)。限制(1)

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

2017-04-15T06:42:01.147 0000 I命令[conn783]查询。集合查询:{orderby:{ts:-1},$query:{br>u\u id:user ki id}}计划摘要:IXSCAN{u\u id:1},IXSCAN{u\u id:1}ntoreurn:1 ntoskip:0 keysinsped:10795
docsExamined:10795 hasSortStage:1 cursorExhausted:1 keydupdates:0
writeConflicts:0 numYields:86 nreturned:1 reslen:771锁:{Global:{br>acquireCount:{r:174},数据库:{acquireCount{r:87},
集合:{acquireCount:{r:87}}}246ms

关于这个问题,有几个值得注意的地方:

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

所以我的问题是:

  • 为什么会这样?我的索引有什么设计缺陷吗
  • 是否值得将索引更改为降序,如{ts:-1}?这些指数之间的实际差异是什么
  • 根据MongoDB文档,当您按顺序排序时,结果将从非“内存”磁盘中选取。这能解释为什么需要100毫秒吗
  • 有人能详细解释我分析日志吗
  • 这是MongoDB想要的行为吗

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

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

db.get集合('位置').查找({u_id:"USR-WOWU"}).排序({ts:-1}).解释(true)

输出:

/*1*/{“queryPlanner”:{“plannerVersion”:1,“namespace”:“db\u name.collection\u name”,“indexFilterSet”:false,“parsedQuery”:{“user\u id”:{“$eq”:“USR-WOWU”}}},“winningPlan”:{“stage”:“FETCH”,“inputStage”:{“stage”:“IXSCAN”,“keyPattern”:{“u id”:1.0,“ts”:-1.0},“indexName”:“u id\u 1\u ts-1”,“isMultiKey”:false,“isUnique”:false,“Issu parse“:false,“isPartial”:false,“indexVersion”:1,“direction”:“forward”,“indexBounds”:{“u id”:[“[\”USR-WOWU\”,\“USR-WOWU\”],“ts”:[“[MaxKey,MinKey]]}}}}},rejectedplan”:[]},“executionStats”:{“executionSuccess”:true,“nReturned”:164,“executionTimeMillis”:119,“totalKeysExamined”:164,“totalDocsExamined”:164,“executionStages”:{“stage”:“FETCH”,“nReturned”:164,“ExecutionTimeMillisesEstimate”:120,“works”:165,“advanced”:164,“needTime”:0,“needYield”:0,“saveState”:3,“restoreState”:3,“isEOF”:1,“Invalides”:0,“docsExamined”:164,“alreadyHasObj”:0,“inputStage”:{“stage”:“IXSCAN”,“nReturned”:164,“executionTimeMillisEstimate”:0,“works”:165,“advanced”:164,“needTime”:0,“saveState”:3,“restoreState”:3,“isEOF”:1,“invalidates”:0,“keyptern”:{“u id”:1.0,“ts”:-1.0},“indexName”:“u id\u 1\u ts-1”,“isMultiKey”:false,“isUnique”:false,“isSparse”:false,“isPartial”:false,“indexVersion”:1,“direction”:“forward”,“indexBounds”:{“u id”:[“[\”USR-WOWU\“,\”USR-WOWU\“],“ts”:[“[MaxKey,MinKey]”]},“keystested”:164,“dupsTested”:0,“dupsDropped”:0,“seenInvalidated”:0},“allplan执行”:[]},“serverInfo”:{“host”:“manish”,“port”:22022,“version”:“3.2.13”,“gitVersion”:“23899209cad60aaafe114f6aea6cb83025ff51bc”},“ok”:1.0}

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

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

我的mongoDB中是否缺少配置或需要任何配置??

共有1个答案

史阳晖
2023-03-14

为什么会这样

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

通过索引此查询以避免内存中排序,可能会获得性能改进。

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

如果我按降序更改索引,如{ts:-1},真的值得吗。

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

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

但是,此查询似乎不再使用。跳过(0)。极限(1)。你能把这些加回去看看性能是否有所提高吗?

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

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

 类似资料:
  • 问题内容: SQL: 用户索引: 个人资料索引 解释 : 上面的查询大约需要0.1221 我怎样才能使其运行更快? 问题答案: 我删除了此查询,因此搜索完成后不会显示总结果数。 似乎是临时解决方案,甚至是永久解决方案。

  • 任何解决这一问题的建议都将不胜感激。或者我们可以用另一种方式来计数?我想补充一些细节。滑动大小是一个事件和窗口大小超过10小时(每秒大约有300个事件),我们需要对每个事件做出反应。所以在这种情况下,我们没有使用Flink提供的窗口。我们使用来存储前面的信息。在中用于触发旧数据的清理作业。最后dinstinct键的数量非常多。

  • 问题内容: 我有一本书得很长。我使用setText()方法在JTextArea中显示它。它冻结了UI,并花费大量时间。我该如何解决? 这是SSCCE: 问题答案: 在与构造GUI分开的单独线程中创建DefaultStyledDocument似乎是创建巨大文本区域的最快方法。DefaultStyledDocument是线程安全的。 这是我用来测试DefaultStyledDocument的代码。我用

  • 目前,我正在开发一个社交媒体网站,用户可以像Facebook一样发布任何内容。现在我已经开发了一个从数据库过滤帖子的高级搜索。例如,数据库中有40,000个条目,我想通过高级搜索过滤行。例如,如果我搜索网站,它会显示正确的条目,但如果我搜索图像或视频,它会重复结果。 我只有40,000行,但在结果中显示了2,51,905个条目。这是我的疑问 我在等你的回应。谢谢.

  • 我遵循这个链接制作一个CRF模型。我使用以下命令制作模型。 模型制作成功,但我的训练数据非常多,花费了太多时间。当我仔细观察系统中发生的事情时。它只使用了我电脑的一个核心 我能否以使用计算机多个核心的方式运行此命令?看起来它是作为单个线程实现的。是否支持多线程?如果是,请分享。

  • 问题内容: 我正在尝试测试从Excel数据连接运行的查询的三种变体。 我有三个单独的数据连接和三个单独的选项卡,它们分别从每个连接获取数据。 每个查询的连接字符串相同,只有命令文本(Oracle SQL)不同。 Excel中是否可以查看每个查询的执行时间? 我专门使用版本 问题答案: 可能是这样的事情(假设所有连接都将其结果放置在工作表中,而不是在数据透视表中): 要运行此命令: +转到VBA编辑