前言
索引在数据库中的作用是不言自明的,它可以使数据查询更加高效,也可以避免全表扫描等低效操作。在 MongoDB 中,索引同样也具有重要的作用,在一些高效查询和大数据量的应用场景中更是不可或缺的。但是,在实际开发中,如何正确使用索引并发挥它的最大威力,则需要我们了解索引扫描方式及其效率,才能在应用中得心应手地使用它。
索引扫描方式
在 MongoDB 中,索引扫描方式可以分为两种:全索引扫描和索引范围扫描。它们的优点和缺点如下:
全索引扫描
全索引扫描是 MongoDB 中最简单、最基础的扫描方式。其操作方式是按照索引字段的顺序对所有索引条目逐一扫描,当检索到需要的数据时就返回,扫描到集合末尾则结束。由于它不需要对数据进行排序,因此速度较快。但是,当数据量大时,随着扫描次数的增加,查询速度会明显下降。
索引范围扫描
索引范围扫描是通过索引范围过滤进行数据扫描,只有满足条件的数据才会被返回。它基本上适用于所有的查询操作,速度相对全索引扫描较慢。但是,在查询大数据量的集合时,它却是最有效的扫描方式。
索引效率对比
为了更加深入了解索引扫描方式的效率和效果,我们可以通过实际的代码实验来对比它们的效率。
假设有一个用户数据库,其中保存了 100 万条数据。首先我们看一下全索引扫描的代码实现:
db.userInfo.find({}).explain("executionStats");
查询的返回结果中包含了执行时间、扫描行数、扫描文档数、查找行数等详细统计信息。假设查询的结果为:
-- -------------------- ---- ------- - -------------- - - ---------------- - -- ----------- - ---------------- ---------------- - ------ ------------- - - -- ------------- - - ------- - ----------- ----------- - --------- -- --------------- - - - -- ---------------- - - ------------------ - ----- ----------- - -------- --------------------- - ------ ------------------- - -- ------------------- - -------- ----------------- - - ------- - ----------- ----------- - -------- ----------------------------- - ----- ------- - -------- ---------- - -------- ---------- - -- ----------- - -- ----------- - ----- -------------- - ----- ------- - -- ------------- - -- ----------- - ---------- -------------- - ------- - -- ------------ - - --------- - -------- ------------ - ------------------------------------------- --------- - - -- ----------- - ---------- -- ---- - --- -
可以看到,在全索引扫描的情况下,查询耗时为 10654ms
,扫描文档数为 1000000
。
接下来是使用索引范围扫描的代码实现。假设我们需要查询年龄在 20 到 30 岁之间的用户:
db.userInfo.find({age:{$gte:20, $lt:30}}).explain("executionStats");
查询结果为:
-- -------------------- ---- ------- - -------------- - - ---------------- - -- ----------- - ---------------- ---------------- - ------ ------------- - - ------ - - - ----- - - ------ - -- - -- - ----- - - ----- - -- - - - -- ------------- - - ------- - -------- ------------ - - ------- - --------- ------------ - - ----- - - -- ----------- - ------ ------------ - ------ --------------- - - ----- - - - -- ---------- - ------ ---------- - ------ ----------- - ------ -------------- - -- ----------- - ---------- ------------- - - ----- - - ------- ------ - - - -- --------------- - - - -- ---------------- - - ------------------ - ----- ----------- - ------- --------------------- - ----- ------------------- - ------- ------------------- - ------- ----------------- - - ------- - -------- ----------- - ------- ----------------------------- - ---- ------- - ------- ---------- - ------- ---------- - -- ----------- - -- ----------- - ----- -------------- - ----- ------- - -- ------------- - -- -------------- - ------- --------------- - -- ------------ - - ------- - --------- ----------- - ------- ----------------------------- - ---- ------- - ------- ---------- - ------- ---------- - -- ----------- - -- ----------- - ----- -------------- - ----- ------- - -- ------------- - -- ------------ - - ----- - - -- ----------- - ------ ------------ - ------ --------------- - - ----- - - - -- ---------- - ------ ---------- - ------ ----------- - ------ -------------- - -- ----------- - ---------- ------------- - - ----- - - ------- ------ - -- -------------- - ------ - - -- ------------ - - --------- - -------- ------------ - ------------------------------------------- --------- - - -- ----------- - ---------- -- ---- - --- -
可以看到,在使用索引范围扫描的情况下,查询耗时仅为 1251ms
,扫描文档数为 100000
,查询速度比全索引扫描快了很多。
总结和指导意义
从以上的实验中我们可以看到,在大数据量的情况下,使用索引范围扫描是比全索引扫描更加高效的,因为它只扫描了包含所需数据的文档,而不需要扫描整个集合。在实际使用中,我们应该根据业务需求和数据量大小来选择合适的索引扫描方式,以达到最优效果。
此外,在设置索引时也需要注意一些细节,例如选择合适的索引字段、建立复合索引等。在查询时,也应该避免使用 $exists
,$regex
等操作符,以减少不必要的数据扫描。
综上所述,正确使用索引扫描方式可以显著提高 MongoDB 数据库的查询效率和程序性能,对于前端开发人员而言具有十分重要的学习和指导意义。
参考资料:
- MongoDB 官方文档
- 《MongoDB 实战》
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64faf5daf6b2d6eab31b93fb