Man*_*edi 1 mongodb database-performance
我有带索引timestamp_1, timestamp_2 and user_id字段的位置集合。执行查询时(您可以在以下日志中看到),然后查询大约需要 3 分钟(175670 毫秒)。我不知道为什么会这样!!我附上了以下 MongoDB-Log。
任何人都可以解释我下面的日志以及如何优化它?
2017-04-12T17:04:33.759+0000 I COMMAND [conn167] query location-collection query: { orderby: { timestamp_1: 1 }, $query: { $and: [ { timestamp_1: { $lte: 14920162944486.0 } }, {timestamp_2: { $gte: 1491993563400.0 } }, { user_id: "jkfjlsjfflki-14asddsd" } ] } } planSummary: IXSCAN { user_id: 1 }, IXSCAN { user_id: 1 } ntoreturn:10007Examined4p4p7Examined4p7s hasSortStage:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:3350 nreturned:67 reslen:176574 锁:{全局:{acquireCount:{r:6702}},数据库:{acquireCount:{r:3351}},集合: {acquireCount: { r: 3351 } } } 175670 毫秒
还有一个问题:我正在创建自己的“_id”字段值,所以这样有什么缺点吗??我只是创建字符串值并期望 mongoDb 索引它没有任何问题。
2017-04-12T17:04:41.979+0000 I COMMAND [conn150] 查询 db.users 查询:{ orderby: { _id: 1 }, $query: { _id: "USR-dfhsddf-14905426shfkjdhfmreturn" } plan :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 } }, Database: {获取计数:{r:1}},集合:{acquireCount:{r:1}}} 2627ms
提前致谢!!
首先回答第二个问题 - 可以使用您自己的 _id 值。MongoDB 将正确索引它。这样做的结果是,您的应用程序现在有责任确保没有重复项。
默认的 MonogDB ObjectId 类型还在值中包含时间戳。这意味着当它是 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 条匹配的记录。在timestamp_1和timestamp_2不使用索引。
MongoDB 将索引存储为 B-TREE 并允许复合索引(https://docs.mongodb.com/manual/indexes/)。您可以测试创建新的索引组合、分析结果并查看哪一种最适合您的应用程序。与所有三个领域的一个复合索引将允许查询分析所有查询字段(中user_id,timestamp_1和timestamp_2只使用索引),这应该减少文件的数量是MongoDB的需要磁盘的读取了。一个潜在的例子是:
db.collection.createIndex({user_id:1, timestamp_1:1, timestamp_2:-1)
Run Code Online (Sandbox Code Playgroud)
该索引将允许 Mongo 查询规划器匹配该user_id字段,然后查找timestamp_1小于该值的结果,然后查找timestamp_2大于其值的任何结果。因为timestamp_1是在之前列出的timestamp_2,匹配的记录已经排序,这也可能让 MongoDB 跳过排序阶段。您需要在您自己的系统上对此进行测试,以验证其性能是否更好。根据集合中文档的基数,您可以尝试将时间戳字段放在 user_id 字段之前。