我的位置集合带有索引timestamp_1, timestamp_2 and user_id
字段。执行查询时(您可以在以下日志中看到)然后查询~3分钟(175670ms)。我不知道为什么会这样!
我附上了MongoDB-Log。
任何人都可以在日志后解释我,我该如何优化它?
2017-04-12T17:04:33.759 + 0000 I COMMAND [conn167]查询 location-collection query:{orderby:{timestamp_1:1},$ query:{ $和:[{timestamp_1:{$ lte:1492016294486.0}},{timestamp_2:{ $ gte:1491993563400.0}},{user_id:" jkfjlsjfflki-14asddsd" }]}} planSummary:IXSCAN {user_id:1},IXSCAN {user_id:1} ntoreturn:1000 ntoskip:0 keysExamined:27254 docsExamined:27254 hasSortStage:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:3350 nreturned:67 reslen:176574 locks:{Global:{ acquireCount:{r:6702}},数据库:{acquireCount:{r:3351}}, 收集:{acquireCount:{r:3351}}} 175670ms
还有一个问题:我正在创造自己的价值" _id"那么这样的任何缺点?我正在创建只是字符串值并期望mongoDb索引没有任何问题。
2017-04-12T17:04:41.979 + 0000 I COMMAND [conn150]查询db.users 查询:{orderby:{_ id:1},$ query:{_ id: " USR-dfhsddf-14905426shfkjdhf" planSummary:IDHACK ntoreturn:1 ntoskip:0 keysExamined:1 docsExamined:1 idhack:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:0 nreturned:1 reslen:1291 locks:{Global:{acquireCount:{r:2}},数据库:{acquireCount: {r:1}},收藏:{acquireCount:{r:1}}} 2627ms
提前致谢!!
答案 0 :(得分:3)
首先回答第二个问题 - 可以将自己的值用于_id。 MongoDB将正确编制索引。这样做的结果是,现在您的应用程序有责任确保不存在重复项。
默认的MonogDB ObjectId类型还包括值中的时间戳。这意味着当_id字段是ObjectId时按_id字段排序将按插入顺序返回结果(或者在创建ObjectId时按顺序返回技术时间戳)。
对于日志输出,查询性能输出值来自Database Profiler。您可以在https://docs.mongodb.com/manual/reference/database-profiler/查看值列表。
查询效果的一个非常有用的工具是explain()
,https://docs.mongodb.com/manual/reference/method/cursor.explain/和https://docs.mongodb.com/manual/reference/explain-results/。您必须在自己的系统上测试查询的执行方式。
您的收藏品似乎在各个字段上有三个不同的索引:timestamp_1
,timestamp_2
和user_id
。
该查询正在比较三个字段:
timestamp_1
小于值timestamp_2
大于值user_id
等于值您还要通过输出中的timestamp_1
字段进行排序。
planSummary: IXSCAN { user_id: 1 }, IXSCAN { user_id: 1 }
表示查询计划程序正在user_id
为查询选择索引,然后再次选择user_id
上的索引用于排序,这不是你真正想要排序的领域。有关参考,请参阅https://groups.google.com/forum/#!topic/mongodb-user/nQlmVdODo-M。
keysExamined:27254
表示索引扫描检查了索引中的27254个键。 docsExamined:27254
表示MongoDB从磁盘中提取了27245个文档来检查内容。 nreturned:67
表示查询结果返回了67个文档。扫描user_id
索引,找到27254个匹配项,然后从集合中检索每个文档。解析这些文档并比较timestamp*
字段,并返回67个匹配的记录。 1}}和timestamp_1
索引未使用。
MongoDB将索引存储为B-TREE并允许复合索引(https://docs.mongodb.com/manual/indexes/)。您可以测试新的索引组合,分析结果,并查看哪种方法最适合您的应用程序。包含所有三个字段的复合索引将允许查询仅使用索引来分析所有查询字段(timestamp_2
,user_id
和timestamp_1
),这应该减少文档的数量MongoDB需要读取磁盘。一个可能的例子是:
timestamp_2
此索引允许Mongo查询规划器匹配db.collection.createIndex({user_id:1, timestamp_1:1, timestamp_2:-1)
字段,然后查找user_id
小于该值的结果,然后查找timestamp_1
大于timestamp_2
的结果它的价值。由于timestamp_1
列在timestamp_2
之前,因此匹配的记录已经排序,这也可能允许MongoDB跳过排序阶段。您需要在自己的系统上进行测试,以验证其性能是否更好。根据集合中文档的基数,您可以尝试将时间戳字段放在user_id字段之前。