解释MongoDB日志输出

解释MongoDB日志输出,mongodb,database-performance,Mongodb,Database Performance,我有一个带有索引timestamp_1、timestamp_2和user_id字段的位置集合。执行查询时(您可以在下面的日志中看到),然后查询需要约3分钟(175670ms)。我不知道为什么会这样!! 我已附上以下MongoDB日志。 有人能解释我的日志吗?我如何优化日志 2017-04-12T17:04:33.759+0000 I命令[conn167]查询 位置集合查询:{orderby:{timestamp_1:1},$query:{ $and:[{timestamp_1:{$lte:149

我有一个带有索引
timestamp_1、timestamp_2和user_id
字段的位置集合。执行查询时(您可以在下面的日志中看到),然后查询需要约3分钟(175670ms)。我不知道为什么会这样!! 我已附上以下MongoDB日志。
有人能解释我的日志吗?我如何优化日志

2017-04-12T17:04:33.759+0000 I命令[conn167]查询 位置集合查询:{orderby:{timestamp_1:1},$query:{ $and:[{timestamp_1:{$lte:149216294486.0}},{timestamp_2:{ $gte:1491993563400.0},{user_id:“jkfjlsjfflki-14asddsd”}]} 计划摘要:IXSCAN{user\u id:1},IXSCAN{user\u id:1} NTORTURN:1000 ntoskip:0检查的密钥数:27254文档检查的密钥数:27254 hasSortStage:1游标已退出:1密钥更新:0写入冲突:0 numYields:3350 nreturned:67 reslen:176574锁:{全局:{ acquireCount:{r:6702},数据库:{acquireCount:{r:3351}, 集合:{acquireCount:{r:3351}}175670ms

还有一个问题:我正在创建我自己的“_id”字段值,这样有什么缺点吗??我只创建字符串值,并希望mongoDb索引它不会出现任何问题

2017-04-12T17:04:41.979+0000 I命令[conn150]查询数据库用户 查询:{orderby:{{u-id:1},$query:{u-id: “USR-dfhsddf-14905426shfkjdhf”}计划摘要:IDHACK返回:1 ntoskip:0密钥已检查:1文档已检查:1 idhack:1 cursorexhousted:1 keyUpdates:0 writeConflicts:0 numields:0 nreturned:1 reslen:1291 锁:{Global:{acquireCount:{r:2}},数据库:{acquireCount: {r:1},集合:{acquireCount:{r:1}}}2627ms


提前感谢

首先回答第二个问题-可以为_id使用您自己的值。MongoDB将正确索引它。这样做的结果是,您的应用程序现在有责任确保没有重复项

默认的MonogDB ObjectId类型还包括值中的时间戳。这意味着,按_id字段排序(当它是ObjectId时)将按插入顺序返回结果(或者在ObjectId是按插入顺序创建时返回技术时间戳)

对于日志输出,查询性能输出值来自数据库探查器。您可以在中查看值列表

一个非常有用的查询性能工具是
explain()
,以及。您必须在自己的系统上测试查询的执行情况

似乎在各个字段的集合上有三个不同的索引:
timestamp\u 1
timestamp\u 2
、以及
user\u id

查询正在比较三个字段:

  • 时间戳_1
    小于一个值
  • 时间戳_2
    大于一个值
  • user\u id
    等于一个值
您还可以通过输出中的
timestamp_1
字段进行排序

planSummary:IXSCAN{user\u id:1},IXSCAN{user\u id:1}
表示查询计划器正在为查询选择
user\u id
上的索引,然后再次选择
user\u id
上的索引以用于排序,这不是您实际想要排序的字段。有关参考,请参阅

keysected:27254
表示索引扫描检查了索引中的27254个键。
docsExamined:27254
意味着MongoDB从磁盘上提取了27245个文档来检查内容。
nreturned:67
说明查询结果返回了67个文档。扫描
用户id
索引,找到27254个匹配项,然后从集合中检索每个文档。解析这些文档,比较
时间戳*
字段,并返回67条匹配记录。不使用
timestamp_1
timestamp_2
索引

MongoDB将索引存储为B树,并允许复合索引()。您可以测试索引的新组合,分析结果,并查看哪一个最适合您的应用程序。包含所有三个字段的复合索引将允许查询仅使用索引分析所有查询字段(
user\u id
timestamp\u 1
、和
timestamp\u 2
),这将减少MongoDB需要从磁盘读取的文档数量。一个可能的例子是:

db.collection.createIndex({user_id:1, timestamp_1:1, timestamp_2:-1)

此索引将允许Mongo查询计划器匹配
用户id
字段,然后查找
时间戳_1
小于该值的结果,然后查找
时间戳_2
大于其值的更多结果。因为
timestamp_1
列在
timestamp_2
之前,匹配的记录已经被排序,这也允许MongoDB跳过排序阶段。您需要在自己的系统上进行测试,以验证其性能是否更好。根据集合中文档的基数,您可以尝试将时间戳字段放在user_id字段之前

首先回答第二个问题-可以为_id使用您自己的值。MongoDB将正确索引它。这样做的结果是,您的应用程序现在有责任确保没有重复项

默认的MonogDB ObjectId类型还包括值中的时间戳。这意味着,按_id字段排序(当它是ObjectId时)将按插入顺序返回结果(或者在ObjectId是按插入顺序创建时返回技术时间戳)

对于日志输出,查询性能输出值来自数据库探查器。您可以在中查看值列表

一个非常有用的查询性能工具是
explain()
,以及。您必须在自己的系统上测试查询的执行情况

似乎在各个字段的集合上有三个不同的索引:<