【发布时间】:2017-10-03 07:03:51
【问题描述】:
我有一个包含 300 万个文档和以下索引的集合:
{ ts : 1 } , {u_id: 1}
请注意,这是两个独立的升序索引,而不是复合索引。
当我运行这个查询时:
db.collection.find({u_id: 'user'}).sort({ts : -1}).skip(0).limit(1)
需要 +100 毫秒。我有以下日志:
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: {
获取计数:{ r:174 } },数据库:{获取计数:{ r:87 } },
集合:{ acquireCount: { r: 87 } } } 246ms
关于这个问题的几个值得注意的点:
- MongoDB 上没有其他负载,即没有其他需要 +100 毫秒的查询
- 这种情况每分钟都在发生;我想我每分钟都在存储数据,所以这种情况正在发生
- 查询流程是先运行读取查询(如上),然后下一个查询是批量插入。此流程每分钟重复一次。
所以我的问题是:
- 为什么会这样?我的索引是否存在设计缺陷?
- 是否值得将索引更改为降序,例如 {ts: -1}?这些索引之间的实际区别是什么?
- 根据 MongoDB 文档,当您按顺序进行排序时,结果将从磁盘而不是“内存”中选择。这是否解释了为什么需要 +100 毫秒?
- 谁能详细解释一下分析日志?
- 这是 MongoDB 的期望行为吗?
当我对该集合运行范围搜索时,也会发生同样的事情;这需要 3-5 秒。
编辑:
我只添加了 {u_id: 1, ts: -1} 索引。删除所有其他索引(_id 除外)。仍然是第一次查询执行需要 +100 毫秒。这不应该发生。
查询:
db.getCollection('locations') .find({u_id: "USR-WOWU"}) .sort({ts: -1}) .explain(true)
输出::
/* 1 */ { “查询计划者”:{ “计划者版本”:1, “命名空间”:“db_name.collection_name”, “indexFilterSet”:假, “解析查询”:{ “用户身份” : { "$eq" : "USR-WOWU" } }, “获胜计划”:{ “阶段”:“获取”, “输入阶段”:{ “阶段”:“IXSCAN”, “键模式”:{ “u_id”:1.0, “ts”:-1.0 }, “indexName”:“u_id_1_ts_-1”, “isMultiKey”:假, “isUnique”:假, “isSparse”:假, “isPartial”:假, “索引版本”:1, “方向”:“前进”, “索引边界”:{ “u_id”:[ "[\"USR-WOWU\",\"USR-WOWU\"]" ], “ts”:[ “[最大键,最小键]” ] } } }, “拒绝计划”:[] }, “执行统计”:{ “执行成功”:真, “nReturned”:164, “执行时间米利斯”:119, “totalKeysExamined”:164, “totalDocsExamined”:164, “执行阶段”:{ “阶段”:“获取”, “nReturned”:164, “executionTimeMillisEstimate”:120, “作品”:165, “高级”:164, “需要时间”:0, “需要产量”:0, “保存状态”:3, “恢复状态”:3, “isEOF”:1, “无效”:0, “docsExamined”:164, “已经有对象”:0, “输入阶段”:{ “阶段”:“IXSCAN”, “nReturned”:164, “执行时间MillisEstimate”:0, “作品”:165, “高级”:164, “需要时间”:0, “需要产量”:0, “保存状态”:3, “恢复状态”:3, “isEOF”:1, “无效”:0, “键模式”:{ “u_id”:1.0, “ts”:-1.0 }, “indexName”:“u_id_1_ts_-1”, “isMultiKey”:假, “isUnique”:假, “isSparse”:假, “isPartial”:假, “索引版本”:1, “方向”:“前进”, “索引边界”:{ “u_id”:[ "[\"USR-WOWU\",\"USR-WOWU\"]" ], “ts”:[ “[最大键,最小键]” ] }, “keysExamined”:164, “dupsTested”:0, “dupsDropped”:0, “seenInvalidated”:0 } }, “所有计划执行”:[] }, “服务器信息”:{ “主机”:“manish”, “端口”:22022, “版本”:“3.2.13”, “gitVersion”:“23899209cad60aaafe114f6aea6cb83025ff51bc” }, “好的”:1.0 }
请将上面的 JSON 和格式复制到任何编辑器中。
在上述查询之后,下一个相同的查询将在约 2 毫秒内响应。但是当我做很少的插入时,一分钟后会重复同样的事情。 (第一次查询需要时间+100ms,然后大约需要2ms。)
在我的 mongoDB 中是否缺少某些东西或需要配置任何东西?
【问题讨论】:
-
您能否引用您的问题来源:'当您按顺序进行排序时,结果将从磁盘而不是“内存中”中选择'。我不确定我明白你的意思。
-
@Vince:感谢指正!!
标签: mongodb performance