假设我启动了一个 mongo db 服务器:
mongo --dbpath=/some/path --port=12345 --storageEnginewiredTiger
然后我运行相同的查询 10 次(忽略第一个,以便它们都在热缓存上),如下所示:
mongo query1.js
我得到的时间是(通过 time
以及 mongodb 记录器验证):
8137ms
8145毫秒
8193毫秒
8091 毫秒
8152毫秒
8110毫秒
8182毫秒
8142毫秒
8133毫秒
8098 毫秒
太棒了——相当一致。所有这些都在大约 100 毫秒内,这是有道理的。
然后我以任何以下方式关闭服务器:
pkill mongod
mongod --dbpath=/some/path --shutdown
mongo shutdown.js
其中 shutdown.js
包含:
db.getSiblingDB('admin').shutdownServer();
然后我重新启动它,使用完全相同的命令,我得到以下时间:
8531ms
8492毫秒
8613毫秒
8555毫秒
8538ms
8512毫秒
8551毫秒
8511毫秒
8608ms
8522毫秒
同样,它们始终在约 100 毫秒内,但它们都处于不同的基线。
如果我再次执行此操作,它可能在 8.3
、8.6
、8.9
或介于两者之间的任何位置。没有其他用户进程处于打开状态(除了那些需要 ssh 进入机器的用户进程)。
我做了如下实验:
当真时:
运行查询 25 次并记录最短的此类运行时间
关闭服务器并重新启动它,等待它监听
这个周末跑了两天,我没有和机器交互,收集了 223 个数据点,最小运行时间从 7.9s
到 8.9s
.如果我没有在两者之间关闭服务器,这不会发生,但同样,我可能会得到 7.9s
的基线,或者我可能会得到 8.9 的基线之一s
。
一个数据点的标准偏差(25 个查询的运行时间)总是非常低(大约 0.06),但在所有查询之间,却非常高。
是否有人对为什么会发生这种情况以及如何防止这种情况有直觉?我试图弄清楚一个查询是否比另一个查询快,但我无法获得一个好的基准来测试。重新启动服务器不是绝对必要的,但它会让我的生活更轻松,因为我并不总是让服务器运行。
最佳答案
MongoDB 使用缓存来为您提供一些查询服务。重新启动服务器时,必须清除一些缓存。 MongoDB 将所有最近使用的数据保存在 RAM 中。如果您为查询创建了索引并且您的工作数据集适合 RAM,则 MongoDB 从内存中提供所有查询。
查询计划保存在缓存中,在 mongo 重启时会清除。因此,第一次运行查询需要时间。请参阅说明(“执行统计”)。
通过 WiredTiger,MongoDB 使用文件系统缓存和 WiredTiger 缓存。默认情况下,从 MongoDB 3.2 开始,WiredTiger 缓存将使用 60% 的 RAM 减去 1 GB 或使用 1 GB,以较大者为准。对于具有高达 10 GB RAM 的系统,这小于或等于 3.0 设置。对于 RAM 超过 10 GB 的系统,配置大于 3.0 设置。
在 MongoDB 3.0 中,WiredTiger 缓存默认使用 1 GB 或已安装物理 RAM 的一半,以较大者为准。
MongoDB 还通过文件系统缓存自动使用机器上的所有空闲内存(文件系统缓存中的数据被压缩)。
关于MongoDB - 重新启动服务器后不同的查询执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33742472/