面试题答案
一键面试1. 优化性能时参数调整策略
- $sort:
- 数据特点与调整:如果数据按照某字段有天然顺序(如时间戳字段),在聚合时可利用此顺序避免额外排序操作。若分析需求需按其他字段排序,应尽量在早期阶段进行排序,因为后续阶段可能利用排序结果做更高效操作。例如,若后续有 $group$ 操作,提前按分组字段排序,$group$ 操作可更高效执行。
- 示例:若集合记录用户操作时间,分析按操作时间顺序的用户行为,可直接按时间字段排序
{ $sort: { operationTime: 1 } }
。
- $limit:
- 数据特点与调整:明确只需要获取部分结果时,尽早使用 $limit$ 限制返回文档数量。比如在做数据预览、只关注前N个结果的分析场景。
- 示例:只需要获取热度最高的前10条数据,可添加
{ $limit: 10 }
。
- $skip:
- 数据特点与调整:用于跳过指定数量的文档。但要注意,随着跳过数量增大,性能可能急剧下降,因为MongoDB需扫描并跳过这些文档。适用于分页场景且页码靠前的情况。若页码靠后,应考虑使用其他分页策略(如基于_id的分页)。
- 示例:分页展示数据,每页10条,要获取第2页数据,可使用
{ $skip: 10, $limit: 10 }
。
2. 不同数据分布和查询模式下的潜在性能风险与应对策略
- $sort:
- 性能风险:在大数据集上对无索引字段排序,会消耗大量内存和CPU资源,若内存不足,可能导致磁盘交换,严重降低性能。
- 应对策略:对排序字段建立索引。若无法建立索引,可考虑分块处理数据,每次处理部分数据进行排序,然后合并结果。
- $limit:
- 性能风险:如果未结合适当的排序和索引,$limit$ 操作可能需要扫描整个数据集才能确定返回的前N条数据,性能较差。
- 应对策略:结合索引和合理排序,如按某个有索引的字段排序后再使用 $limit$。例如按热度字段排序获取前N条热门数据,需对热度字段建立索引。
- $skip:
- 性能风险:当跳过大量文档时,MongoDB需要扫描并跳过这些文档,性能随跳过数量增加而下降。
- 应对策略:对于分页场景,采用基于_id的分页方式。记录上次查询的最后一个_id,下次查询时使用
{ _id: { $gt: lastId } }
来获取下一页数据,避免使用大的 $skip$ 值。