node.js - 尽可能快地在 MongoDB 中加载一百万条记录
问题描述
我有一个包含超过 3000 万条记录的大型数据库,我如何知道我的服务器的瓶颈在哪里以及为什么我的查询需要时间。
我的数据库索引良好,当我选择记录时,并不是所有检查的记录。
我知道加载一百万条记录是不寻常的事情,但是如果我想尽快加载这些记录,如何知道为什么查询需要时间?有监控工具吗?
换句话说,如果有人问:我有一个很好的 CPU 和 SSD,为什么这个查询需要这么长时间,答案应该是什么?
在我看来,我认为这与 SSD 速度和用于查找记录的核心数量有关,而 NodeJS 仅使用一个核心。那正确吗?
查询示例:
db.bios.find( { birth: { $gt: new Date('2019-01-01'), $lt: new Date('2000-01-01') } } )
birth
在我的情况下,这里是唯一索引的。
解决方案
我有一个很好的 CPU 和 SSD 为什么这个查询需要这么长时间,答案应该是什么?
您还需要考虑是否有足够的 RAM 来容纳索引。之后你需要做一些查询优化
如何知道为什么查询需要时间?有监控工具吗?
查看分析您的数据库。这将记录慢查询,您可以看到选择了哪些索引以及每个查询花费了多长时间。
这应该让您对数据库性能有一个很好的了解。您可以使用一些工具来可视化这些数据(这里有一篇博客文章详细介绍了使用 Logstash 和 Kibana)。
NodeJS 只使用一个核心。那正确吗?
NodeJS 主要在单个线程中运行,但您可以通过cluster或worker生成更多线程。但是数据库在多个线程上运行在它自己的进程中,并且应该在与 Node 应用程序不同的服务器上运行。
用于加载许多文档的快速查询
每个数据库请求要加载多少个文档会有一个最佳点。这取决于文档的大小和查询。
来自mongoDB 文档:
排序操作
如果 MongoDB 无法使用索引以请求的排序顺序获取文档,则排序操作中所有文档的总大小加上少量开销必须小于 32 兆字节。
例如,这可以处理大约 500 个文档。
添加排序顺序以在birth
字段上按递增顺序排列。确保索引您的排序字段 ( birth
),然后使用 获取前 500 个文档limit
。取最后一个返回的文档,并使用它的值birth
来限制您的下一个查询。然后继续循环,直到找到所有文档。
第一个查询是
db.bios.find( { birth: { $gt: new Date('2019-01-01'), $lt: new Date('2000-01-01') } } )
birth
如果返回的最后一个对象有'2019-01-05'
第二个查询是
db.bios.find( { birth: { $gt: new Date('2019-01-05'), $lt: new Date('2000-01-01') } }
等等。
如果你使用Mongoose,我写了一个小的npm 包来简化这个操作(但它没有测试,因为它最初只用于个人项目)
更新:硬件要求
没有简单的方法来找出什么会阻碍您的 MongoDB 实例,因为它取决于您的使用情况 - 大量索引和复合索引 - 较小的文档或较大的文档 - 经常写入一次读取或经常更新(您的文档是否会增长?) - 复杂的聚合
测试这一点的最佳方法是通过缩放测试,因为 MongoDB 应该线性缩放。如果您预计会有 1TB 的集合,请尝试使用相同的索引和架构创建一个 1GB 大小的示例集合。在便宜、弱的服务器上运行它。对它运行查询并查看资源使用情况(CPU、RAM、磁盘 I/O、网络)
您可以查看有关此主题的一些不错的文档和博客文章:
架构如果您需要非常快速且频繁地加载大量数据,您还应该考虑重新设计架构。
我怀疑您是否在 UI 中显示 100 万行数据。如果您正在加载数据来处理它,可以将处理后的数据保存为新集合(例如,用于图表)。如果您需要搜索它,请使用查询/过滤器。如果需要跨多个字段进行全文搜索,请将其合并到一个字段中。或者考虑使用针对此类操作优化的数据库(例如 Casandra)
推荐阅读
- ruby-on-rails - 如何使用 simple_form 在 Rails 中向数据库提交表单?
- c - CTypes 的问题 - 调用 C dll 函数
- cassandra - Cassandra 在 GCP 上通过 VPN 进行 DC 间同步
- php - Xero Api,如何在单个银行交易中创建“多个项目”
- node.js - 我无法在adonis js中上传文件,移动不起作用
- ios - 从推送通知中使用导航控制器打开特定视图
- soap - 尝试 POST 到 Cybersource Simple Order API 时收到 No WS-Security Header 错误
- spring - Spring 微服务实例未向在 8761 以外的端口中运行的 Eureka 注册
- shared-hosting - 重定向 https 网址
- javascript - 缩放到搜索(标记)位置 Google Maps API