在使用 Mongoose 进行 MongoDB 数据库操作时,我们难免会使用到 populate 方法来进行关联表查询。然而,由于数据库查询性能较低,过多的 populate 操作会严重影响程序性能。本文将介绍几种优化 Mongoose 的 populate 查询性能的方法,从而提高系统的性能。
1. 使用 Mongoose 自带的缓存机制
Mongoose 自带缓存机制可以自动缓存最后一次查询结果。在一定的情况下,可以减少查询数据库的次数。
-- -------------------- ---- ------- ----- ---------- - --- ----------------- ----- ------ --- ----- ---------- - --- ----------------- ------- ------ ------------------------------- ---- -------- ------ ------- -------- ------ --- ----- ---- - ---------------------- ------------ ----- ---- - ---------------------- ------------ ----- -------- ---------- - ----- ---- - ----- ----------------------------------------- -------------------- ------------------------------ - ----------- -------- ----------------------------------- ----- -------- ------------ - ----- ---- - ----- ------------------------------ ----------------------- - ------------- --------
2. 使用 Lean() 方法
Mongoose 中 populate 方法查询时默认返回的是 Mongoose Model 实例,但是如果只是单纯地取出关联文档中的数据,不需要对它进行任何的操作,我们可以使用lean()
方法将返回的结果转换为普通 JavaScript 对象,从而避免了实例化的过程,提高程序性能。
-- -------------------- ---- ------- ----- ---------- - --- ----------------- ----- ------ --- ----- ---------- - --- ----------------- ------- ------ ------------------------------- ---- -------- ------ ------- -------- ------ --- ----- ---- - ---------------------- ------------ ----- ---- - ---------------------- ------------ ----- -------- ---------- - ----- ---- - ----- ----------------------------------------- ------------------- -------- ------------------------------ - ----------- --------
3. 使用 pipeline 强化查询
查询时如果有多个 $lookup 查询操作,Mongoose 需要分发多个查询到 MongoDB 进行结果集合的组装,如果有多个 $lookup 查询,则需要分配多个查询到数据库集合。在用 Lean() 方法转化为普通对象或数组,这种方式显然会带来很大的查询性能损耗。
可以使用 pipeline 强化查询,通过 $lookup 将多个集合进行连接查询后返回结果。
-- -------------------- ---- ------- ----- ---------- - --- ----------------- ----- ------ --- ----- ---------- - --- ----------------- --------- ------------------------------- ------ ------- -------- ------ --- ----- ------------- - --- ----------------- ------- ------------------------------- -------- ------ --- ----- ---- - ---------------------- ------------ ----- ------- - ------------------------- --------------- ----- ---- - ---------------------- ------------ ----- -------- ---------------------------- - ----- -------- - - -------- ----- ------------------------------ --------- ------ -------- ----------- ----------- ------------- ------ --- ----------- --------- ------ ---------- --------------------------- ------- --------- ------ ----------- ----------- ------ ------------- --------- --- ------------- -- ------ ----- -------------------------------- - ----- -------- ------ - ----- ---- - ----- ----------------------------------------------------- ------------------ - -------
4. 大规模数据优化
如果你需要处理的数据集太大,无法通过 Mongoose 的缓存机制和 Lean() 方法来优化查询性能,可以尝试以下方法提高查询效率:
1. 使用只包含对象 ID 的文档
这种方式通常应用于只需要获取文档的 ID 的场景,例如在搜索记录中返回 ID 是否存在,如果存在,则根据 ID 加载其详细信息。
2. 使用分页功能
分页是一种有效的方式来降低查询负载,您可以通过以下方式使用分页:
const pageSize = 10; const pageNumber = 5; const query = Post.find({}); query.limit(pageSize); query.skip(pageSize * (pageNumber - 1)); query.sort({createdAt: 'desc'}); query.populate('user').exec();
这里我们设置页面大小为 10,要查询的页数为 5。首先,使用 limit()
方法限制结果集的大小。然后,使用skip()
方法跳过其它分页结果。接下来,使用sort()
方法指定以创建时间为准对结果集进行排序。最后,使用populate()
加载关联表数据。
3. 使用 MongoDB 的索引
索引是一种数据库结构,可以人为地指定字段或组合字段的值,使其能够更快地进行搜索。使用索引可以提高查询速度,从而提高数据库的性能。
-- -------------------- ---- ------- ----- ---------- - --- ----------------- ----- ------ --- ----- ---------- - --- ----------------- ------- ------ ------------------------------- ---- -------- ------ ------- -------- ------ --- ----- ---- - ---------------------- ------------ ----- ---- - ---------------------- ------------ ----------------------- ---- ----- -------- ---------- - ----- ---- - ----- ----------------------------------------- -------------------- ------------------------------ -
在这个例子中,我们添加了索引到name
字段。这个字段在User
模型中使用。通过这种方式,查询将更快,应用程序性能将得到提高。
总结:
延迟加载是现代应用程序中非常重要的优化。用得好延迟加载可以减少不必要的性能问题,并使你的程序性能达到新的高度。虽然并不可能在所有情况下都使用延迟加载来进行数据库优化,但是,上述优化方式可以极大地提高程序的性能,使得程序能够更好地处理大量的数据。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/647a82cc968c7c53b063a245