mongodb - 300k 文档的 MongoDB 查询耗时超过 30 秒
问题描述
好的,如标题中所述,我有“性能问题”,我需要从集合中获取所有文档,但这需要很长时间。Players 集合包含大约 300k 个小尺寸文档,服务中的查询如下所示:
async getAllPlayers() {
const players = await this.playersCollection.find({}, {projection: { playerId: 1, name: 1, surname: 1, shirtNumber: 1, position: 1 }}).toArray();
return players;
}
总大小为 6.4MB。我正在使用 Fastify 适配器、fastify-compress 和 mongodb 本机驱动程序。如果我删除投影,几乎需要一分钟。
知道如何改进吗?
解决方案
我得到的最佳时间是 8 秒,这fast-json-stringify
给我超过 30 万条记录的 10 多秒提升:
'use strict'
// run fresh mongo
// docker run --name temp --rm -p 27017:27017 mongo
const fastify = require('fastify')({ logger: true })
const fjs = require('fast-json-stringify')
const toString = fjs({
type: 'object',
properties: {
playerId: { type: 'integer' },
name: { type: 'string' },
surname: { type: 'string' },
shirtNumber: { type: 'integer' },
}
})
fastify.register(require('fastify-mongodb'), {
forceClose: true,
url: 'mongodb://localhost/mydb'
})
fastify.get('/', (request, reply) => {
const dataStream = fastify.mongo.db.collection('foo')
.find({}, {
limit: 300000,
projection: { playerId: 1, name: 1, surname: 1, shirtNumber: 1, position: 1 }
})
.stream({
transform(doc) {
return toString(doc) + '\n'
}
})
reply.type('application/jsonl')
reply.send(dataStream)
})
fastify.get('/insert', async (request, reply) => {
const collection = fastify.mongo.db.collection('foo')
const batch = collection.initializeOrderedBulkOp();
for (let i = 0; i < 300000; i++) {
const player = {
playerId: i,
name: `Name ${i}`,
surname: `surname ${i}`,
shirtNumber: i
}
batch.insert(player);
}
const { result } = await batch.execute()
return result
})
fastify.listen(8080)
在任何情况下,您都应该考虑:
- 对输出进行分页
- 或将数据推送到存储桶(如 S3)并返回给客户端一个 URL 以直接下载文件,这将大大加快该过程,并将您的 node.js 进程从此数据流中保存
请注意,node.js 中的压缩是一个繁重的过程,因此会大大降低响应速度。nginx 代理默认添加它,而无需在业务逻辑服务器中实现它。
推荐阅读
- java - maven pom 无法导入预期版本
- c++ - MCS 锁实现的问题
- encryption - OpenSSL - 正确的 RSA 签名生成和验证
- java - JProfiler 否定 -parameter 编译器参数
- javascript - 无法通过谷歌表单发送确认电子邮件
- amazon-web-services - 如何将 boto3 安装到 EMR 集群上以与 Jupyter Notebook 一起使用
- office-js - Outlook 上下文加载项:规则集合不起作用
- tensorflow - Protobuf 没有将 .proto 文件转换为 .py 文件
- google-api - G Suite API 中 Etag 字段的用途是什么?
- amp-html - 如何让 AMP Cookie 同意模式对话框背景正常工作?