您在初始查询中观察到的性能问题可能是以下问题之一(按可能性的粗略顺序排列):
1) 您的应用程序/Web 服务在首次请求时需要初始化(即分配内存、设置连接池、解析 DNS 等)。
2) 您请求的索引或数据尚未在内存中,因此需要加载。
3) The 查询优化器在第一个请求上运行可能需要更长的时间,因为它正在比较查询模式的计划执行。
通过以下方式测试查询会非常有帮助mongo
shell,并隔离开销是否与 MongoDB 或您的 Web 服务相关(而不是像您所做的那样对两者进行计时)。
以下是与 MongoDB 相关的一些注释。
Caching
MongoDB 没有内存中文档的“缓存”时间。它使用内存映射文件进行磁盘 I/O,内存中的文档基于您的活动查询(您最近加载的文档/索引)以及可用内存。操作系统的虚拟内存管理器负责caching,并且通常会遵循最近最少使用 (LRU) 算法来决定将哪些页面交换出内存。
内存使用情况
预期的行为是,随着时间的推移,MongoDB 将逐渐使用所有可用内存来存储活动的工作数据集。
查看您提供的db.stats()
数字(假设这是你的only数据库),看起来您的数据库大小当前约为 1Gb,因此您应该能够将所有内容保留在 10Gb 总 RAM 内,除非:
- 有其他进程竞争内存
- 你已经重新启动了你的
mongod
服务器和那些文档/索引尚未被请求
在 MongoDB 2.2 中,有一个新的touch服务器重新启动后,您可以使用命令将索引或文档加载到内存中。这只应在初始启动时使用以“预热”服务器,否则您可能会毫无帮助地强制实际“活动”数据脱离内存。
例如,在 Linux 系统上,您可以使用top
命令并应该看到:
- virtual bytes/VSIZE 往往是整个数据库的大小
- 如果服务器没有运行其他进程,则常驻字节数/RSIZE 将是机器的总内存(包括文件系统缓存内容)
-
mongod
不应使用交换(因为文件是内存映射的)
您可以使用mongostat快速查看您的mongod
活动..或更有用的是,使用类似的服务MMS随着时间的推移监控指标。
查询优化器
MongoDB查询优化器每约 1,000 次写入操作就比较查询模式的计划执行情况,然后缓存“获胜”查询计划,直到优化器下次运行..或者您显式调用explain()关于该查询。
这应该是一个简单的测试:在mongo
外壳与.explain()
并查看毫秒计时,以及扫描的索引条目和文档的数量。 explain() 的时间不是查询运行的实际时间,因为它包括比较计划的成本。典型的执行会快得多..并且您可以在您的中查找慢速查询mongod
log.
默认情况下,MongoDB 将记录所有慢于 100 毫秒的查询,因此这为寻找要优化的查询提供了一个良好的起点。您可以使用以下命令调整慢速 ms 值--slowms配置选项,或使用Database Profiler命令。
进一步阅读 MongoDB 文档:
- Caching
- 检查服务器内存使用情况
- 数据库分析器
- Explain
- 监控与诊断