面试题答案
一键面试索引设计与使用
- 分析查询条件:确定查询中频繁使用的字段,例如如果经常根据
created_at
字段和status
字段查询,那么在这两个字段上创建索引。- 单字段索引:如果查询主要基于单个字段,如
user_id
,可以创建单字段索引db.collection.createIndex({user_id: 1})
,1表示升序, -1表示降序。 - 复合索引:当多个字段一起用于查询时,创建复合索引。例如经常按
category
和created_at
查询,创建db.collection.createIndex({category: 1, created_at: 1})
,索引字段的顺序很重要,按照查询条件中字段出现的顺序以及过滤性强弱来排列。
- 单字段索引:如果查询主要基于单个字段,如
- 覆盖索引:若查询返回的字段与索引包含的字段相同,可利用覆盖索引。例如查询
title
和author
字段,并且在这两个字段上有复合索引,MongoDB可以直接从索引中获取数据,而无需回表操作,大大提高查询效率。
避免略过大量结果提升查询效率
- 合理使用分页参数:在使用
skip
和limit
进行分页时,skip
在大数据量下效率较低,因为它需要从集合开头略过指定数量的文档。建议使用_id
进行分页,例如上次查询返回的最后一个文档的_id
为last_id
,下次查询使用db.collection.find({_id: {$gt: last_id}}).limit(10)
,这样可以避免每次都从集合开头略过大量数据。 - 利用排序与索引:如果查询需要排序,确保排序字段在索引中,并且顺序与索引一致。例如按
created_at
降序排序查询,索引应是db.collection.createIndex({created_at: -1})
,这样可以利用索引的有序性快速进行排序操作,提高查询效率。 - 批量查询:将大查询拆分为多个小的批量查询,减少单次查询的数据量,同时也有助于避免内存占用过高导致的性能问题。例如将百万条记录分成每次1万条的小批量进行处理。